感觉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. POJ2396:Budget(带下界的网络流)

    Budget Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 8946   Accepted: 3327   Special ...

  2. Codeforces Round #526 (Div. 2) D. The Fair Nut and the Best Path

    D. The Fair Nut and the Best Path 题目链接:https://codeforces.com/contest/1084/problem/D 题意: 给出一棵树,走不重复的 ...

  3. bzoj 3513 [MUTC2013]idiots FFT 生成函数

    [MUTC2013]idiots Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 806  Solved: 265[Submit][Status][Di ...

  4. java实现极简的LRU算法

    import java.util.LinkedHashMap;import java.util.Map; /** * LRU (Least Recently Used)  */public class ...

  5. java摘要

    **idea 注册 Licensed to ilanyu License Server: http://idea.iteblog.com/key.php 1.文件上传下载 http://blog.cs ...

  6. 联系人数据存储Demo源代码

    源码下载地址:07-联系人数据存储.zip35.8 KB // MJPerson.h // //  MJPerson.h //  07-联系人数据存储 // //  Created by apple ...

  7. django执行sql

    http://docs.30c.org/djangobook2/chapter10/ def first_names(self, last_name): cursor = connection.cur ...

  8. swift 之嵌套的理解 func chooseStepFunction(backwards: Bool) -> (Int) -> Int

    http://blog.csdn.net/lzx_322/article/details/28861199 swift 函数使用前面需要添加 func 有返回值需要使用-> 后面添加返回类型 , ...

  9. python基础===python内置函数大全

    python python内建函数 一.数学运算类 abs(x) 求绝对值1.参数可以是整型,也可以是复数2.若参数是复数,则返回复数的模 complex([real[, imag]]) 创建一个复数 ...

  10. 设计模式之笔记--简单工厂模式(Simple Factory)

    简单工厂模式(Simple Factory) 类图 描述 简单工厂: 一个抽象产品类,可以派生多个具体产品类: 一个具体工厂类: 工厂只能创建一个具体产品. 应用场景 汽车接口 public inte ...