感觉border的性质还是挺神奇的

一个border的性质是$S$有长度为$len$的border当且仅当对$\forall i\equiv j\left(\bmod(n-len)\right)$有$S_i=S_j$,也就是说它有长度为$len-i$的循环节(末尾多出来的部分需要和开头一样),画个图就知道这个性质是对的

所以我们把整个字符串分成长度为$n-len$的许多组,记$\text{pre}_i=S_{1\cdots i},\text{suf}_i=S_{i\cdots n}$

一个结论是:如果不存在$(n-len)|i$使得$suf_{i+1}\ne pre_{n-i}$,那么存在长度为$len$的border(这里的“不等于”只考虑$1\ne0$的情况,不考虑问号)

我们来证明这个结论,如果存在$(n-len)|i$使得$\text{suf}_{i+1}\ne\text{pre}_{n-i}$,那么存在不相等的两组,所以不存在长度为$len$的border

否则分出来的任意两组都相同,即是说$S$有长度为$n-len$的循环节,这就证明了它有长度为$len$的border

所以我们要做的就是快速判断$suf_{i+1}$是否等于$pre_{n-i}$,直接用正串的0和反串的1做卷积即可,最后枚举$len$和$n-len$的倍数判断,总时间复杂度$O(n\log_2n)$

#include<stdio.h>
#include<math.h>
#include<string.h>
typedef double du;
const int maxn=1048576;
const du eps=1e-7;
typedef long long ll;
struct complex{
	du x,y;
	complex(du a=0,du b=0){x=a;y=b;}
};
complex operator+(complex a,complex b){return complex(a.x+b.x,a.y+b.y);}
complex operator-(complex a,complex b){return complex(a.x-b.x,a.y-b.y);}
complex operator*(complex a,complex b){return complex(a.x*b.x-a.y*b.y,a.x*b.y+a.y*b.x);}
void swap(complex&a,complex&b){
	complex c=a;
	a=b;
	b=c;
}
int rev[maxn],N;
complex w[20][maxn];
void pre(int n){
	int i,j,k;
	for(N=1,k=0;N<n;N<<=1)k++;
	for(i=0;i<N;i++)rev[i]=(rev[i>>1]>>1)|((i&1)<<(k-1));
	for(i=2,k=0;i<=N;i<<=1){
		for(j=0;j<i;j++)w[k][j]=complex(cos(j*M_PI/(i/2)),sin(j*M_PI/(i/2)));
		k++;
	}
}
void fft(complex*a,int on){
	int i,j,k,f;
	complex t;
	for(i=0;i<N;i++){
		if(i<rev[i])swap(a[i],a[rev[i]]);
	}
	f=0;
	for(i=2;i<=N;i<<=1){
		for(j=0;j<N;j+=i){
			for(k=0;k<i>>1;k++){
				t=w[f][k];
				t.y*=on;
				t=t*a[i/2+j+k];
				a[i/2+j+k]=a[j+k]-t;
				a[j+k]=a[j+k]+t;
			}
		}
		f++;
	}
	if(on==-1){
		for(i=0;i<N;i++)a[i].x/=N;
	}
}
char s[500010];
complex a[maxn],b[maxn];
int main(){
	int n,i,j;
	bool flag;
	ll ans;
	scanf("%s",s);
	n=strlen(s);
	for(i=0;i<n;i++){
		a[i]=s[i]=='0';
		b[i]=s[n-1-i]=='1';
	}
	pre(n<<1);
	fft(a,1);
	fft(b,1);
	for(i=0;i<N;i++)a[i]=a[i]*b[i];
	fft(a,-1);
	ans=n*(ll)n;
	for(i=1;i<n;i++){
		flag=1;
		for(j=i;j<n;j+=i){
			if(fabs(a[n-1-j].x)>eps||fabs(a[n-1+j].x)>eps){
				flag=0;
				break;
			}
		}
		if(flag)ans^=(n-i)*(ll)(n-i);
	}
	printf("%lld",ans);
}

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

  1. 【LOJ6436】【PKUSC2018】神仙的游戏(NTT)

    [LOJ6436][PKUSC2018]神仙的游戏(NTT) 题面 LOJ 题解 看到\(zsy\)从\(PKUSC\)回来就秒掉了这种神仙题 吓得我也赶快看了看\(PKUSC\)都有些什么神仙题 然 ...

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

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

  3. BZOJ5372: PKUSC2018神仙的游戏

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

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

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

  5. 【loj6436】【pkusc2018】神仙的游戏

    Portal --> pkuscD2T2(loj6436) Solution 个人觉得是道很好的法法塔题qwq 一开始的时候想偏了想到了另一种法法塔处理字符串匹配之类的奇怪技巧(万径人踪灭qwq ...

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

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

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

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

  8. loj6436【PKUSC2018】神仙的游戏

    $|S| \le 5 \times 10^5$ 题解 这题直接用通配符匹配的套路会错,因为重复部分的$?$可能同时被当做了$0$和$1$ 有长度为$i$的公共前缀后缀等价于有长度为$n-i$的循环节: ...

  9. LOJ6436. 「PKUSC2018」神仙的游戏 [NTT]

    传送门 思路 首先通过各种手玩/找规律/严谨证明,发现当\(n-i\)为border当且仅当对于任意\(k\in[0,i)\),模\(i\)余\(k\)的位置没有同时出现0和1. 换句话说,拿出任意一 ...

随机推荐

  1. Windows下查看某个端口被哪个服务占用

    1.查看某个端口是否被占用 打开命令行,输入:netstat -ano | findstr "3306" 2.查看端口被哪个服务占用 tasklist | findstr “PID ...

  2. TestRedis

    import org.junit.Before; import org.junit.Test; import redis.clients.jedis.Jedis; import java.util.H ...

  3. Eclipse工具栏太多,自定义工具栏,去掉调试

    Window --> Customize Perspective... --> Tool Bar Visibility 去掉勾选debug  Tip:最新版本Customize Persp ...

  4. Intelij idea新窗口打开项目设置

    1.idea 打开后 file->setting   2.appearance&behave->system setting->open project in new win ...

  5. 嵌入式上 iscsi实现

    前言 去年公司设备(haisi3516)上需要提供iscsi的功能,于是花了几天时间探究了下.linux内核(2.6.xx)支持iscsi,只是我发现当时我们设备的内核编译时没有选上,于是重新编译了内 ...

  6. Jmeter4.0启动闪退问题解决方案

    jmeter:4.0 jdk版本:1.8 在Jmeter.bat的最后添加pause可以让Jmeter启动停止: 添加了pause进行强制停止在启动命令页面,查看到Jmeter报错信息如下: 第一次解 ...

  7. 1.shell快速入门

    shell是什么?shell是一个命令行解释器,它提供了一个像linux内核发送请求以便运行程序的界面系统程序,用户可以用shell来启动.挂起.停止甚至是编写一些程序.说白了,shell就是用来和内 ...

  8. 【 sysbench 性能基准测试 】

    度娘解释:sysbench是一款开源的多线程性能测试工具,可以执行CPU/内存/线程/IO/数据库等方面的性能测试. 目前支持的数据库支持:MySQL,pgsql,oracle 这3种数据库. 安装s ...

  9. python变现实现新浪微博登陆

    新浪微博的登陆现在是越来越那个了,以前的模拟浏览器登陆新浪微博貌似也越来不管用了 登陆信息由以前的form变成了现在javascript,javascript的加载居然用了一个javascript的函 ...

  10. 关于ES6(ES2015)开发记坑

    ES2015(以下简称ES6)在开发过程中遇到的问题: 1,必须显示声明变量 //es5中可解释为全局变量 a=5; //es6中报错:a is not defined a=5 2,对于递归调用方式必 ...