博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
BZOJ5372 PKUSC2018神仙的游戏(NTT)
阅读量:5280 次
发布时间:2019-06-14

本文共 1426 字,大约阅读时间需要 4 分钟。

  首先有一个想法,翻转串后直接卷积看有没有0匹配上1。但这是必要而不充分的因为在原串和翻转串中?不能同时取两个值。

  先有一些结论:

  如果s中长度为len的前缀是border,那么其存在|s|-len的循环节(最后一段不一定完整)。

  如果已知len不是s的循环节,那么显然len的因子也不是s的循环节。

  如果位置差为len的两个位置无法匹配,那么len不是s的循环节。

  于是可得:如果位置差为len的两个位置无法匹配,那么长度为|s|-(len的因子)的前缀不是border。

  可以发现其实问号出现冲突的原因就在于此,即某两个01的位置差为len,而问号在两者之间且与其中一个的位置差是len的因子。

  那么这是充分的,即只要不会被筛掉则一定是border。

  那么我们卷完后只要枚举长度去看他的倍数有没有被筛掉就可以了。由调和级数,复杂度O(nlogn)。

  LOJ过了,BZOJ上不出意外地T掉了。

 

#include
#include
#include
#include
#include
#include
using namespace std;int read(){ int x=0,f=1;char c=getchar(); while (c<'0'||c>'9') { if (c=='-') f=-1;c=getchar();} while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar(); return x*f;}#define N 1050000#define P 998244353 #define inv3 332748118int n,t,s[N],a[N],b[N],f[N],r[N];long long ans;int ksm(int a,int k){ if (k==0) return 1; int tmp=ksm(a,k>>1); if (k&1) return 1ll*tmp*tmp%P*a%P; else return 1ll*tmp*tmp%P;}void DFT(int n,int *a,int p){ for (int i=0;i
>1);k++,w=1ll*w*wn%P) { int x=a[k],y=1ll*w*a[k+(i>>1)]%P; a[k]=(x+y)%P,a[k+(i>>1)]=(x-y+P)%P; } } }}void mul(int n){ DFT(n,a,3),DFT(n,b,3); for (int i=0;i
>1]>>1)|(i&1)*(t>>1); memset(a,0,sizeof(a));memset(b,0,sizeof(b)); for (int i=0;i
0); memset(a,0,sizeof(a));memset(b,0,sizeof(b)); for (int i=0;i
0); for (int i=1;i

 

  

转载于:https://www.cnblogs.com/Gloid/p/9449034.html

你可能感兴趣的文章
性能调优攻略
查看>>
ie6解决png图片透明问题
查看>>
瞬间的永恒
查看>>
2019-8-5 考试总结
查看>>
JS中实现字符串和数组的相互转化
查看>>
web service和ejb的区别
查看>>
Windows Azure Cloud Service (29) 在Windows Azure发送邮件(下)
查看>>
CS61A Efficiency 笔记
查看>>
微信上传素材返回 '{"errcode":41005,"errmsg":"media data missing"}',php5.6返回
查看>>
div或者p标签单行和多行超出显示省略号
查看>>
Elasticsearch 滚动重启 必读
查看>>
Hadoop基本概念
查看>>
java.util.zip压缩打包文件总结一:压缩文件及文件下面的文件夹
查看>>
浅说 apache setenvif_module模块
查看>>
MySQL--数据插入
查看>>
重新学习python系列(二)? WTF?
查看>>
shell脚本统计文件中单词的个数
查看>>
SPCE061A学习笔记
查看>>
sql 函数
查看>>
hdu 2807 The Shortest Path 矩阵
查看>>