「LibreOJ NOI Round #2」不等关系

解题思路

令 \(F(k)\) 为恰好有 \(k\) 个大于号不满足的答案,\(G(k)\) 表示钦点了 \(k\) 个大于号不满足,剩下随便填的方案数。

枚举有多少个大于号被钦点了,\(F(0)=\sum_{i=0}^n G(i)(-1)^i\) 。

对于一个只有小于号限制的序列的方案数就是每一个小于号链接的联通块里分配的数字顺序固定,块与块之间随便排,令 \(sz[i]\) 表示第 \(i\) 个联通块的大小,方案数也就是 $ \dfrac{n!}{\prod_{i=1}^msz[i]!}$

令 \(dp[i]\) 表示前 \(i\) 个数,\(s_{i}\) 不强制改为小于号的 \(\prod_{i=1}^m (-1)^m \dfrac{1}{sz[i]!}\) 乘上容斥系数之和之和,令 \(p[i]\) 表示前 \(i\) 个字符的大于号数量。\(i\) 是一个联通块的右边界,考虑枚举左边界 \(j\) 计算贡献得到转移。

\[dp[i]=
\begin{cases}
s_i =0 & dp[i]=(-1)^{p[i-1]}\sum_{j=0}^{i-1}dp[j]\times (-1)^{p[j]}\dfrac{1}{(i-j)!}
\\ otherwise & dp[i] = 0
\end{cases}
\]

答案的式子就是 \(Ans = n!\times dp[n+1]\) ,

显然可以分治FFT优化转移,复杂度 \(O(n\log^2n)\) 。

code

/*program by mangoyang*/
#include<bits/stdc++.h>
#define inf (0x7f7f7f7f)
#define Max(a, b) ((a) > (b) ? (a) : (b))
#define Min(a, b) ((a) < (b) ? (a) : (b))
typedef long long ll;
using namespace std;
template <class T>
inline void read(T &x){
int ch = 0, f = 0; x = 0;
for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = 1;
for(; isdigit(ch); ch = getchar()) x = x * 10 + ch - 48;
if(f) x = -x;
}
const int N = 1 << 22, mod = 998244353, G = 3;
char s[N];
int js[N], p[N], a[N], b[N], inv[N], dp[N], n;
inline void up(int &x, int y){
x = x + y >= mod ? x + y - mod : x + y;
}
namespace poly{
int rev[N], len, lg;
inline int Pow(int a, int b){
int ans = 1;
for(; b; b >>= 1, a = 1ll * a * a % mod)
if(b & 1) ans = 1ll * ans * a % mod;
return ans;
}
inline void timesinit(int lenth){
for(len = 1, lg = 0; len <= lenth; len <<= 1, lg++);
for(int i = 0; i < len; i++)
rev[i] = (rev[i>>1] >> 1) | ((i & 1) << (lg - 1));
}
inline void dft(int *a, int sgn){
for(int i = 0; i < len; i++)
if(i < rev[i]) swap(a[i], a[rev[i]]);
for(int k = 2; k <= len; k <<= 1){
int w = Pow(G, (mod - 1) / k);
if(sgn == -1) w = Pow(w, mod - 2);
for(int i = 0; i < len; i += k){
int now = 1;
for(int j = i; j < i + (k >> 1); j++){
int x = a[j], y = 1ll * a[j+(k>>1)] * now % mod;
a[j] = x + y >= mod ? x + y - mod : x + y;
a[j+(k>>1)] = x - y < 0 ? x - y + mod : x - y;
now = 1ll * now * w % mod;
}
}
}
if(sgn == -1){
int Inv = Pow(len, mod - 2);
for(int i = 0; i < len; i++) a[i] = 1ll * a[i] * Inv % mod;
}
}
}
using poly::Pow;
inline void solve(int l, int r){
if(l == r){
if(l) dp[l] = p[l-1] & 1 ? mod - dp[l] : dp[l];
if(l != n + 1) dp[l] = p[l] & 1 ? mod - dp[l] : dp[l];
if(l && s[l] == '<') dp[l] = 0;
return;
}
int mid = (l + r) >> 1;
solve(l, mid);
poly::timesinit(2 * (r - l + 1));
for(int i = l; i <= mid; i++) a[i-l] = dp[i];
for(int i = 1; i <= r - l + 1; i++) b[i] = inv[i];
poly::dft(a, 1), poly::dft(b, 1);
for(int i = 0; i < poly::len; i++)
a[i] = 1ll * a[i] * b[i] % mod;
poly::dft(a, -1);
for(int i = mid + 1; i <= r; i++) up(dp[i], a[i-l]);
for(int i = 0; i < poly::len; i++) a[i] = b[i] = 0;
solve(mid + 1, r);
}
int main(){
scanf("%s", s + 1), n = strlen(s + 1);
js[0] = inv[0] = 1;
for(int i = 1; i <= n + 1; i++){
js[i] = 1ll * js[i-1] * i % mod;
inv[i] = Pow(js[i], mod - 2);
}
for(int i = 1; i <= n; i++)
p[i] = p[i-1] + (s[i] == '>');
dp[0] = 1;
solve(0, n + 1);
cout << 1ll * js[n+1] * dp[n+1] % mod;
return 0;
}

「LibreOJ NOI Round #2」不等关系的更多相关文章

  1. LOJ575. 「LibreOJ NOI Round #2」不等关系 [容斥,分治FFT]

    LOJ 思路 发现既有大于又有小于比较难办,使用容斥,把大于改成任意减去小于的. 于是最后的串就长成这样:<<?<?<??<<<?<.我们把一段连续的& ...

  2. LibreOJ #507. 「LibreOJ NOI Round #1」接竹竿

    二次联通门 : LibreOJ #507. 「LibreOJ NOI Round #1」接竹竿 /* LibreOJ #507. 「LibreOJ NOI Round #1」接竹竿 dp 记录一下前驱 ...

  3. 「LibreOJ NOI Round #1」验题

    麻烦的动态DP写了2天 简化题意:给树,求比给定独立集字典序大k的独立集是哪一个 主要思路: k排名都是类似二分的按位确定过程. 字典序比较本质是LCP下一位,故枚举LCP,看多出来了多少个独立集,然 ...

  4. #509. 「LibreOJ NOI Round #1」动态几何问题

    下面给出部分分做法和满分做法 有一些奇妙的方法可以拿到同样多的分数,本蒟蒻只能介绍几种常见的做法 如果您想拿18分左右,需要了解:质因数分解 如果您想拿30分左右,需要了解:一种较快的筛法 如果您想拿 ...

  5. #510. 「LibreOJ NOI Round #1」动态几何问题

    题目: 题解: 几何部分,先证明一下 \(KX = \sqrt{a},YL = \sqrt{b}\) 设左侧的圆心为 \(O\) ,连接 \(OK\) ,我们有 \(OK = r\). 然后有 \(r ...

  6. #507. 「LibreOJ NOI Round #1」接竹竿 dp

    题目: 题解: 我们考虑把每对花色相同的牌看作区间. 那么如果我们设 \(f_i\) 表示决策在 \([1,i]\) 内的最优答案. 那么有 \(f_i = max\{max\{(f_{j-1}+\s ...

  7. LOJ#510. 「LibreOJ NOI Round #1」北校门外的回忆(线段树)

    题面 传送门 题解 感谢\(@M\_sea\)的代码我总算看懂题解了-- 这个操作的本质就是每次把\(x\)的\(k\)进制最低位乘\(2\)并进位,根据基本同余芝士如果\(k\)是奇数那么最低位永远 ...

  8. LOJ 510: 「LibreOJ NOI Round #1」北校门外的回忆

    题目传送门:LOJ #510. 题意简述: 给出一个在 \(K\) 进制下的树状数组,但是它的实现有问题. 形式化地说,令 \(\mathrm{lowbit}(x)\) 为在 \(K\) 进制下的 \ ...

  9. 「LibreOJ NOI Round #2」单枪匹马

    嘟嘟嘟 这题没卡带一个\(log\)的,那么就很水了. 然后我因为好长时间没写矩阵优化dp,就只敲了一个暴力分--看来复习还是很关键的啊. 这个函数显然是从后往前递推的,那么令第\(i\)位的分子分母 ...

随机推荐

  1. TCP网络程序设计

    tcp_server.c #include<stdio.h>#include<sys/socket.h>#include<string.h>#include< ...

  2. EasyEarth三维可视化解决方案——智慧河长

    EasyEarth—— 为河长装上“千里眼.顺风耳” 为各级河长办应急指挥.任务指派. 实绩考核提供快速直观的 高效.精准.智能化决策平台. 河长制背景 我国治水工作呈现出新老问题交织态势,河湖管理保 ...

  3. SDN上机第三次作业

    1. 利用Mininet仿真平台构建如下图所示的网络拓扑,配置主机h1和h2的IP地址(h1:10.0.0.1,h2:10.0.0.2),测试两台主机之间的网络连通性 使用miniedit进行创建操作 ...

  4. IDEA文件查找功能失效(ctrl+shift+N)

    由于断电.蓝屏引起的强制关机等情况,会导出IDEA文件查找功能失效,Enter file name窗口输入的文字显示红色,无法查出需要的文件.  解决方法: 可以点击File,选择Invalidate ...

  5. 网络营销CPA、CPS、CPM、CPT、CPC 是什么

    网络营销之所以越来越受到重视一个主要的原因就是因为“精准”.相比较传统媒体的陈旧广告形式,网络营销能为广告主带来更为确切的效果与回报,更有传统媒体所没有的即时互动性.很多企业借助于精准的网络营销成为人 ...

  6. Web.config 文件例子

    php - 如何使用web.config重写IIS UrlRewriteModule中的网页的URL? <?xml version="1.0" encoding=" ...

  7. Python3之logging模块浅析

    Python3之logging模块浅析   目录 Python3之logging模块浅析 简单用法 日志与控制台同时输出 一个同时输出到屏幕.文件的完成例子 日志文件截取 日志重复打印问题解决 问题分 ...

  8. kubectl -n ingress-nginx exec nginx-ingress-controller-78bd49949c-t22bl -- cat /etc/nginx/nginx.conf

    kubectl -n ingress-nginx exec nginx-ingress-controller-78bd49949c-t22bl -- cat /etc/nginx/nginx.conf

  9. Grid数字或金额千分位或保留两位小数

    formatter: 'number', formatoptions: { thousandsSeparator: "", decimalPlaces: 2 }

  10. mysql用户添加执行存储过程权限