【LOJ#575】【LNR#2】不等关系(容斥,动态规划,分治FFT)

题面

LOJ

题解

一个暴力\(dp\),设\(f[i][j]\)表示考虑完了前\(i\)个位置,其中最后一个数在前面所有数中排名是第\(j\)大,那么转移的时候枚举一下当前数是第几大,并且满足不等式的限制就可以了,然后拿前缀和优化一下就可以做到\(O(n^2)\)。
我们把所有连续的<看成一段,这样子题目就变成了每次要选出一段连续的上升序列,然后相邻两个连续段之间必须满足前一段的末尾要大于后一段的开头。
显然这个大于号是不好处理的,如果我们能够任意就很好做了。
这些>,即段与段之间的分割的位置的大小情况,如果至少有\(i\)个随意,方案数是\(g[i]\),那么对于答案的贡献就是\((-1)^ig[i]\)。
再考虑一个\(dp\),我们假设分割出来的所有段中,第\(i\)段的长度是\(a[i]\)。设\(f[i][j]\)表示考虑完了前\(i\)段,选出了\(j\)个上升序列的方案数,这样子就至少有\(i-j\)个位置是非法的。转移的话枚举把哪一段作为一段上升序列,那么就是:
\[f[i][j]=\sum_{k=0}^{i-1}f[k][j-1]*{n-s[k]\choose s[i]-s[k]}\]
其中\(s\)是\(a\)的前缀和。
不难发现第二维用处不大,因为容斥系数只有\(\pm 1\),所以可以把容斥系数带进去直接带进去而不需要额外记录第二维来辅助计算。
于是转移就变成了:
\[f[i]=-\sum_{k=0}^{i-1}f[k]{n-s[k]\choose s[i]-s[k]}\]
发现拆开之后可以卷积,然后有一项是\((s[i]-s[k])!\)不太好弄,因为\(s\)足够小,所以把\(i\)变到\(s[i]\)位置卷,这样子\(s[i]-s[k]\)就变成了\(i-k\),那么对于非\(s[i]\)的位置,把它强制弄成\(0\)。这样子拿分治\(FFT\)卷一下就好了。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define MOD 998244353
#define MAX 524288
inline int read()
{int x=0;bool t=false;char ch=getchar();while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();if(ch=='-')t=true,ch=getchar();while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();return t?-x:x;
}
int fpow(int a,int b){int s=1;while(b){if(b&1)s=1ll*s*a%MOD;a=1ll*a*a%MOD;b>>=1;}return s;}
int W[MAX],r[MAX];
void NTT(int *P,int opt,int len)
{int N,l=0;for(N=1;N<len;N<<=1)++l;for(int i=0;i<N;++i)r[i]=(r[i>>1]>>1)|((i&1)<<(l-1));for(int i=0;i<N;++i)if(i<r[i])swap(P[i],P[r[i]]);for(int i=1;i<N;i<<=1){int w=fpow(3,(MOD-1)/(i<<1));W[0]=1;for(int k=1;k<i;++k)W[k]=1ll*W[k-1]*w%MOD;for(int j=0,p=i<<1;j<N;j+=p)for(int k=0;k<i;++k){int X=P[j+k],Y=1ll*W[k]*P[i+j+k]%MOD;P[j+k]=(X+Y)%MOD;P[i+j+k]=(X+MOD-Y)%MOD;}}if(opt==-1){reverse(&P[1],&P[N]);for(int i=0,inv=fpow(N,MOD-2);i<N;++i)P[i]=1ll*P[i]*inv%MOD;}
}
int jc[MAX],jv[MAX],inv[MAX];
int n,a[MAX],ans,cnt;char s[MAX];
bool book[MAX];
int A[MAX],B[MAX],f[MAX];
void CDQ(int l,int r)
{if(l==r){if(l==0)f[l]=1;else if(!book[l])f[l]=0;else f[l]=1ll*f[l]*(MOD-jv[n-l])%MOD;return;}int mid=(l+r)>>1;CDQ(l,mid);for(int i=l;i<=mid;++i)A[i-l]=1ll*f[i]*jc[n-i]%MOD;for(int i=1;i<=r-l+1;++i)B[i]=jv[i];int N;for(N=1;N<=r-l+1+mid-l+1;N<<=1);NTT(A,1,N);NTT(B,1,N);for(int i=0;i<N;++i)A[i]=1ll*A[i]*B[i]%MOD;NTT(A,-1,N);for(int i=mid+1;i<=r;++i)f[i]=(f[i]+A[i-l])%MOD;for(int i=0;i<N;++i)A[i]=B[i]=0;CDQ(mid+1,r);
}
int C(int n,int m){if(n<0||m<0||n<m)return 0;return 1ll*jc[n]*jv[m]%MOD*jv[n-m]%MOD;}
int main()
{scanf("%s",s+1);n=strlen(s+1)+1;for(int i=1;i<n;++i)if(s[i]=='>')book[i]=true,++cnt;inv[0]=inv[1]=jc[0]=jv[0]=1;for(int i=2;i<=n;++i)inv[i]=1ll*inv[MOD%i]*(MOD-MOD/i)%MOD;for(int i=1;i<=n;++i)jc[i]=1ll*jc[i-1]*i%MOD;for(int i=1;i<=n;++i)jv[i]=1ll*jv[i-1]*inv[i]%MOD;CDQ(0,n);/*f[0]=1;for(int i=1;i<=n;++i)if(book[i])for(int j=0;j<i;++j)f[i]=(f[i]+MOD-1ll*f[j]*C(n-j,i-j)%MOD)%MOD;*/for(int i=0;i<=n;++i)ans=(ans+f[i])%MOD;if(cnt&1)ans=(MOD-ans)%MOD;printf("%d\n",ans);return 0;
}

转载于:https://www.cnblogs.com/cjyyb/p/11149241.html

【LOJ#575】【LNR#2】不等关系(容斥,动态规划,分治FFT)相关推荐

  1. 「LibreOJ NOI Round #2」不等关系 (dp+NTT分治)

    description 戳我看题目哦 solution 有一道非常相似的题目 一棵树,每条边限制两个端点的大小关系(限制 a[u]>a[v]a[u]>a[v]a[u]>a[v] 或 ...

  2. loj#2542 [PKUWC2018]随机游走 (概率期望、组合数学、子集和变换、Min-Max容斥)

    loj#2542 [PKUWC2018]随机游走 (概率期望.组合数学.子集和变换.Min-Max容斥) 很好很有趣很神仙的题! 题目链接: https://loj.ac/problem/2542 题 ...

  3. LOJ #2542 [PKUWC2018]随机游走 (概率期望、组合数学、子集和变换、Min-Max容斥)

    很好很有趣很神仙的题! 题目链接: https://loj.ac/problem/2542 题意: 请自行阅读 题解首先我们显然要求的是几个随机变量的最大值的期望(不是期望的最大值),然后这玩意很难求 ...

  4. [LOJ#3124][CTS2019]氪金手游(概率 + 树形 DP + 容斥)

    Address 洛谷 P5405 LOJ #3124 Solution 先考虑如果以某个点(下面定为 111 )为根时,如果所有的限制二元组 (u,v)(u,v)(u,v) 都满足 uuu 是 vvv ...

  5. 【LOJ#6072】苹果树(矩阵树定理,折半搜索,容斥)

    [LOJ#6072]苹果树(矩阵树定理,折半搜索,容斥) 题面 LOJ 题解 emmmm,这题似乎猫讲过一次... 显然先\(meet-in-the-middle\)搜索一下对于每个有用的苹果数量,满 ...

  6. loj#2542. 「PKUWC2018」随机游走(MinMax容斥 期望dp)

    题意 题目链接 Sol 考虑直接对询问的集合做MinMax容斥 设\(f[i][sta]\)表示从\(i\)到集合\(sta\)中任意一点的最小期望步数 按照树上高斯消元的套路,我们可以把转移写成\( ...

  7. LOJ#3124. 「CTS2019 | CTSC2019」氪金手游 容斥+DP

    神仙容斥+DP可还行. code: #include <cstdio> #include <cmath> #include <vector> #include &l ...

  8. [LOJ#3119][Luogu5405][CTS2019]氪金手游(DP+容斥)

    先考虑外向树的做法,显然一个点在其子树内第一个出现的概率等于它的权值除以它子树的权值和.于是f[i][j]表示i的子树的权值和为j时,i子树内所有数的相互顺序都满足条件的概率,转移直接做一个背包卷积即 ...

  9. [LOJ575]不等关系

    题目 传送门 to LOJ 思路 或许你会考虑硬上 d p \tt dp dp 么?极困难.因为 大小关系的本质是有向图拓扑序.尽管这个图长相特殊,但是仍然要素过多.与之相反的是,全都是 < 时 ...

最新文章

  1. 科学计算工具NumPy(1):ndarray的创建于数据类型
  2. php tp3 操作绑定到类,快速入门 17:操作绑定到类
  3. python3实现mysql导出excel
  4. android推送接口,推送API
  5. Qt connect信号连接的几种写法
  6. 创建型模式—单例模式
  7. jenkins job config.xml结构
  8. javaScript实现E-mail 验证
  9. 如何把创建ECS(CreateInstance)作为触发器来触发函数计算
  10. C#静态类,静态构造函数,静态变量
  11. Flink Forward Asia 2020 -- Keynote 总结
  12. 拓端tecdat|r语言空间可视化绘制道路交通安全事故地图
  13. vue 导出excel文件
  14. 全球与中国智能灯市场深度研究分析报告
  15. 拟凸函数和凸函数的区别
  16. 通过R语言实现平稳时间序列的建模--基础(ARMA模型)
  17. 数据分析案例-基于随机森林算法的商品评价情感分析
  18. vue2 watch监听中调用methods方法
  19. DM数据库使用dmmdf工具修改db_magic
  20. 使用Namebench查找更快的DNS服务器

热门文章

  1. 3.15 使用仿制图章工具 [原创Ps教程]
  2. PS抠图方法、技巧大集合
  3. 怪物猎人世界计算机内存不足,《怪物猎人世界》吃CPU原因曝光 官方:加载内容过多...
  4. YOLOV4 中断恢复训练 --resume
  5. python内容审核_我们看下Python黄图批量鉴别审核(多线程版)!学习学习
  6. python画蜡烛致敬烈士_用matplotlib制作的比较满意的蜡烛图
  7. Windows office更新 应用程序无法正常启动0xc0000142
  8. CS5212替代瑞昱RTD2166_DP转VGA方案|低成本替代RTD2166方案|CS5212电路转换方案
  9. android studio升级到了最新Bumblebee版本,git无法使用
  10. miui9修改 更新 服务器,无需ROOT,三步屏蔽MIUI9系统更新提示