[LOJ6436]神仙的游戏
感觉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]神仙的游戏的更多相关文章
- 【LOJ6436】【PKUSC2018】神仙的游戏(NTT)
[LOJ6436][PKUSC2018]神仙的游戏(NTT) 题面 LOJ 题解 看到\(zsy\)从\(PKUSC\)回来就秒掉了这种神仙题 吓得我也赶快看了看\(PKUSC\)都有些什么神仙题 然 ...
- LOJ #6436. 「PKUSC2018」神仙的游戏(字符串+NTT)
题面 LOJ #6436. 「PKUSC2018」神仙的游戏 题解 参考 yyb 的口中的长郡最强选手 租酥雨大佬的博客 ... 一开始以为 通配符匹配 就是类似于 BZOJ 4259: 残缺的字符串 ...
- BZOJ5372: PKUSC2018神仙的游戏
传送门 Sol 自己还是太 \(naive\) 了,上来就构造多项式和通配符直接匹配,然后遇到 \(border\) 相交的时候就 \(gg\) 了 神仙的游戏蒟蒻还是玩不来 一个小小的性质: 存在长 ...
- BZOJ5372: [Pkusc2018]神仙的游戏
BZOJ5372: [Pkusc2018]神仙的游戏 https://lydsy.com/JudgeOnline/problem.php?id=5372 分析: 如果\(len\)为\(border\ ...
- 【loj6436】【pkusc2018】神仙的游戏
Portal --> pkuscD2T2(loj6436) Solution 个人觉得是道很好的法法塔题qwq 一开始的时候想偏了想到了另一种法法塔处理字符串匹配之类的奇怪技巧(万径人踪灭qwq ...
- LOJ6436 [PKUSC2018] 神仙的游戏 【FFT】
题目分析: 题目要求前后缀相同,把串反过来之后是一个很明显的卷积的形式.这样我们可以完成初步判断(即可以知道哪些必然不行). 然后考虑一下虽然卷积结果成立,但是存在问号冲突的情况. 箭头之间应当不存在 ...
- [LOJ6436][PKUSC2018]神仙的游戏
loj description 给你一个只有01和?的字符串,问你是否存在一种把?改成01的方案使串存在一个长度为\(1-n\)的\(border\).\(n\le5\times10^5\) sol ...
- loj6436【PKUSC2018】神仙的游戏
$|S| \le 5 \times 10^5$ 题解 这题直接用通配符匹配的套路会错,因为重复部分的$?$可能同时被当做了$0$和$1$ 有长度为$i$的公共前缀后缀等价于有长度为$n-i$的循环节: ...
- LOJ6436. 「PKUSC2018」神仙的游戏 [NTT]
传送门 思路 首先通过各种手玩/找规律/严谨证明,发现当\(n-i\)为border当且仅当对于任意\(k\in[0,i)\),模\(i\)余\(k\)的位置没有同时出现0和1. 换句话说,拿出任意一 ...
随机推荐
- Different Integers 牛客多校第一场只会签到题
Given a sequence of integers a1, a2, ..., an and q pairs of integers (l1, r1), (l2, r2), ..., (lq, r ...
- 构建一个类jq的函数库
jqfree core var $ = function(selector, context) { return new $.fn.init(selector, context); }; $.fn = ...
- VC++中编译C出错:error C2143: syntax error : missing ';' before 'type'
转摘自:http://preceo.blog.51cto.com/6225017/1130931 近来写程序时发现了一个问题,用 VC 编译 C语言是 总是提示一个错误:error C2143: sy ...
- PowerDesigner使用教程(转)
PowerDesigner是一款功能非常强大的建模工具软件,足以与Rose比肩,同样是当今最著名的建模软件之一.Rose是专攻UML对象模型的建模工具,之后才向数据库建模发展,而PowerDesign ...
- 转:使用 Nginx Upload Module 实现上传文件功能
普通网站在实现文件上传功能的时候,一般是使用Python,Java等后端程序实现,比较麻烦.Nginx有一个Upload模块,可以非常简单的实现文件上传功能.此模块的原理是先把用户上传的文件保存到临时 ...
- go的websocket实现
websocket分为握手和数据传输阶段,即进行了HTTP握手 + 双工的TCP连接 RFC协议文档在:http://tools.ietf.org/html/rfc6455 握手阶段 握手阶段就是普通 ...
- python学习笔记 IO 文件读写
读写文件是最常见的IO操作.python内置了读写文件的函数. 读写文件前,我们先必须了解一下,在磁盘上读写文件的功能都是由操作系统完成的,现代操作系统不允许普通的程序直接对磁盘进行操作,所以, 读写 ...
- 浏览器内核测试 v0.99
操作系统: Windows 7 浏览器内核: WebKit 内核(Chrome) 内核版本是: WebKit 537.36( Chrome 49.0.2593.0 S) 完整代码: Mozilla/ ...
- SFTP获取数据文件
使用SFTP:客户端从服务端获取数据文件 客户机: 用户:client IP:13.00.00.11 服务端: 用户:server IP:16.00.00.66 1.在客户端的根目录下,执行下面的命令 ...
- 【SQL】服务器环境下的SQL
一.大型数据库的三层体系结构 web服务器:比如在淘宝页面上,输入“牛肉干”,就是web服务器来处理,提交给应用服务器. 应用服务器:在获取到“牛肉干”这个请求后,应用服务器决定如何汇集结果,并进行相 ...