题目

画一画就会发现一些奇诡的性质

首先如果\(len\)为一个\(\operatorname{border}\),那么必然对于\(\forall i\in [1,len]\),都会有\(s_i=s_{n-len+i}\)

我们大力扩展一下这个性质,发现当\(len\)为一个\(\operatorname{border}\)时,我们把这个整个字符串按照\(n-len\)来分段,每一段都是完全相等的,最后的不完整的一段也肯定是之前的某一个前缀

换句话说,任取\(i,j\)在\(\operatorname{mod}\ (n-len)\)意义下相等,那么\(s_i\)和\(s_j\)也必须相等

于是我们发现通配符变得没有意义了,我们把\(0,1\)分别位于那些位置求出来,如果有一个\(1\)位于\(i\)位置,有一个\(0\)位于\(j\)位置,那么如果存在\(i\equiv j(mod\ x)\),那么\(n-x\)不可能成为一个\(\operatorname{border}\)

显然如果\(x|\operatorname{abs}(i-j)\),那么\(i\equiv j(mod\ x)\)

也就是说我们处理出\(0,1\)位置两两之差的绝对值,之后调和级数一下就能判断出那些不是\(\operatorname{border}\)了

显然现在问题被转化成了一道\(\operatorname{FFT}\)板子题

代码

#include<bits/stdc++.h>
#define re register
#define LL long long
const int mod=998244353;
const int maxn=1<<20;
int n,len,Inv;char S[500005];
int rev[maxn],a[maxn],b[maxn],c[maxn];
inline int ksm(int a,int b) {
int S=1;
for(;b;b>>=1,a=1ll*a*a%mod) if(b&1) S=1ll*S*a%mod;
return S;
}
inline void NTT(int *f,int *g) {
for(re int i=0;i<len;i++)
if(i<rev[i]) std::swap(g[i],g[rev[i]]),std::swap(f[i],f[rev[i]]);
for(re int i=2;i<=len;i<<=1) {
int ln=i>>1,og1=ksm(3,(mod-1)/i);
for(re int t,og=1,l=0;l<len;l+=i,og=1)
for(re int x=l;x<l+ln;++x,og=1ll*og*og1%mod)
t=1ll*f[x+ln]*og%mod,f[x+ln]=(f[x]-t+mod)%mod,f[x]=(f[x]+t)%mod,
t=1ll*g[x+ln]*og%mod,g[x+ln]=(g[x]-t+mod)%mod,g[x]=(g[x]+t)%mod;
}
for(re int i=0;i<len;i++) f[i]=1ll*f[i]*g[i]%mod;
for(re int i=0;i<len;i++) if(i<rev[i]) std::swap(f[i],f[rev[i]]);
for(re int i=2;i<=len;i<<=1) {
int ln=i>>1,og1=ksm((mod+1)/3,(mod-1)/i);
for(re int t,og=1,l=0;l<len;l+=i,og=1)
for(re int x=l;x<l+ln;++x,og=1ll*og*og1%mod)
t=1ll*f[x+ln]*og%mod,f[x+ln]=(f[x]-t+mod)%mod,f[x]=(f[x]+t)%mod;
}
for(re int i=0;i<len;i++) f[i]=1ll*f[i]*Inv%mod;
}
inline int abs(int x) {return x>=0?x:-x;}
int main() {
scanf("%s",S);n=strlen(S);
for(re int i=0;i<n;i++) {
if(S[i]=='0') a[n-i]++;
if(S[i]=='1') b[i]++;
}
len=1;while(len<n+n+1) len<<=1;Inv=ksm(len,mod-2);
for(re int i=0;i<len;i++) rev[i]=rev[i>>1]>>1|((i&1)?len>>1:0);
NTT(a,b);
for(re int i=1;i<n+n;i++) c[abs(i-n)]+=a[i];
LL ans=0;
for(re int i=1;i<n;i++) {
int flag=0;
for(re int j=i;j<=n;j+=i) flag|=(c[j]>0);
if(!flag) ans^=1ll*(n-i)*(n-i);
}
ans^=1ll*n*n;std::cout<<ans;
return 0;
}

[PKUSC2018]神仙的游戏的更多相关文章

  1. BZOJ5372: [Pkusc2018]神仙的游戏

    BZOJ5372: [Pkusc2018]神仙的游戏 https://lydsy.com/JudgeOnline/problem.php?id=5372 分析: 如果\(len\)为\(border\ ...

  2. BZOJ5372: PKUSC2018神仙的游戏

    传送门 Sol 自己还是太 \(naive\) 了,上来就构造多项式和通配符直接匹配,然后遇到 \(border\) 相交的时候就 \(gg\) 了 神仙的游戏蒟蒻还是玩不来 一个小小的性质: 存在长 ...

  3. bzoj 5372: [Pkusc2018]神仙的游戏

    Description 小D和小H是两位神仙.他们经常在一起玩神仙才会玩的一些游戏,比如"口算一个4位数是不是完全平方数". 今天他们发现了一种新的游戏:首先称s长度为len的前缀 ...

  4. LOJ6436 [PKUSC2018] 神仙的游戏 【FFT】

    题目分析: 题目要求前后缀相同,把串反过来之后是一个很明显的卷积的形式.这样我们可以完成初步判断(即可以知道哪些必然不行). 然后考虑一下虽然卷积结果成立,但是存在问号冲突的情况. 箭头之间应当不存在 ...

  5. loj 6436 PKUSC2018 神仙的游戏

    传送门 好妙蛙 即串\(s\)长度为\(n\)首先考虑如果一个长度为\(len\)的\(border\)存在,当且仅当对所有\(i\in[1,len],s[i]=s[n-len+i]\),也就是所有模 ...

  6. BZOJ5372 PKUSC2018神仙的游戏(NTT)

    首先有一个想法,翻转串后直接卷积看有没有0匹配上1.但这是必要而不充分的因为在原串和翻转串中?不能同时取两个值. 先有一些结论: 如果s中长度为len的前缀是border,那么其存在|s|-len的循 ...

  7. [LOJ6436][PKUSC2018]神仙的游戏

    loj description 给你一个只有01和?的字符串,问你是否存在一种把?改成01的方案使串存在一个长度为\(1-n\)的\(border\).\(n\le5\times10^5\) sol ...

  8. [PKUSC2018]神仙的游戏(FFT)

    给定一个01?串,对所有len询问是否存在一种填法使存在长度为len的border. 首先有个套路的性质:对于一个长度为len的border,这个字符串一定有长度为n-len的循环节(最后可以不完整) ...

  9. LOJ #6436. 「PKUSC2018」神仙的游戏(字符串+NTT)

    题面 LOJ #6436. 「PKUSC2018」神仙的游戏 题解 参考 yyb 的口中的长郡最强选手 租酥雨大佬的博客 ... 一开始以为 通配符匹配 就是类似于 BZOJ 4259: 残缺的字符串 ...

随机推荐

  1. Linux基本使用命令

    一.常用命令归纳分类 课外网站  http://man.linuxde.net/               http://www.jb51.net/linux/               http ...

  2. Ruby 安装 – Windows

    Ruby 安装 – Windows 下面列出了在 Windows 机器上安装 Ruby 的步骤. 注意:在安装时,您可能有不同的可用版本. - Window 系统下,我们可以使用 RubyInstal ...

  3. 模拟+算贡献——cf1195D

    比赛的时候没看到模数,用java大数在写,最后看到的时候已经慌了.. 把贡献算清楚就可以 下面是贡献的推导 有五位数 abcde * 10个 有两位数 fg * 3 个 那么这两种数组成的情况就是 a ...

  4. NX二次开发-创建图纸尺寸表达式抑制UF_DRF_add_controlling_exp

    #include <uf.h> #include <uf_modl.h> #include <uf_drf.h> #include <uf_obj.h> ...

  5. [JZOJ 5129] 字符串

    题意:统计本质不同的串的个数. 思路: 显然后缀自动机,对于每个串建一个\(SAM\)统计即可. #include <bits/stdc++.h> using namespace std; ...

  6. Comet OJ - 2019 六一欢乐赛

    传送门 #A: 思路:等差数列求和,看成俩次1+2+…+ n,多加的n减去,所以 ans = n*(n+1) - n. AC代码: #include<iostream> #include& ...

  7. 剑指offer——09青蛙跳台阶

    题目描述 一只青蛙一次可以跳上1级台阶,也可以跳上2级.求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果).   题解: 说俗一点,就是找规律: 不不,首先,我们分析一下,青蛙第一 ...

  8. 剑指offer——03替换空格

    题目描述 请实现一个函数,将一个字符串中的每个空格替换成“%20”.例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy.   注意事项: <剑指o ...

  9. CSS如何让文字垂直居中?

    在说到这个问题的时候,也许有人会问CSS中不是有vertical-align属性来设置垂直居中的吗?即使是某些浏览器不支持我只需做少许的CSS Hack技术就可以啊!所以在这里我还要啰嗦两句,CSS中 ...

  10. 2.用Python套用Excel模板,一键完成原亮样式

    from xlutils.copy import copy import xlrd import xlwt tem_excel=xlrd.open_workbook('日统计.xls',formatt ...