首页 > 代码库 > Codeforces 235C. Cyclical Quest
Codeforces 235C. Cyclical Quest
传送门
写的时候挺蛋疼的。
刚开始的时候思路没跑偏,无非就是建个SAM然后把串开两倍然后在SAM上跑完后统计贡献。但是卡在第二个样例上就是没考虑相同的情况。
然后开始乱搞,发现会出现相同串的只有可能是由一个串无限拼接构成的串,于是上了个KMP来搞循环串..然后就没有然后了
基本上一直处于改了这个错误后又被另一个错误卡着的状态,后来没办法了,翻题解..
然后发现只需要在SAM的节点上开个标记就行了...
越学越傻啊...
至于为什么KMP会挂掉..求dalao评论指出
//Codeforces 235C//by Cydiater//2017.1.22#include <iostream>#include <queue>#include <map>#include <iomanip>#include <cstring>#include <string>#include <cstdlib>#include <cstdio>#include <algorithm>#include <cmath>#include <ctime>#include <bitset>#include <set>#include <vector>using namespace std;#define ll long long#define up(i,j,n) for(int i=j;i<=n;i++)#define down(i,j,n) for(int i=j;i>=n;i--)#define cmax(a,b) a=max(a,b)#define cmin(a,b) a=min(a,b)const int MAXN=2e6+5;const int oo=0x3f3f3f3f;int rnk[MAXN],N,Right[MAXN],M,len,ans,flag[MAXN];char s[MAXN];struct SAM{ int now,cnt,son[MAXN][26],step[MAXN],pre[MAXN],label[MAXN]; SAM(){now=cnt=1;} void Extend(int nxt){ int p=now,np=++cnt;now=np; step[np]=step[p]+1;Right[np]=1; for(;(!son[p][nxt])&&p;p=pre[p])son[p][nxt]=np; if(!p)pre[np]=1; else{ int q=son[p][nxt],nq; if(step[q]==step[p]+1)pre[np]=q; else{ step[(nq=++cnt)]=step[p]+1; memcpy(son[nq],son[q],sizeof(son[q])); pre[nq]=pre[q]; pre[np]=pre[q]=nq; for(;son[p][nxt]==q;p=pre[p])son[p][nxt]=nq; } } } void Toposort(){ up(i,1,cnt)label[step[i]]++; up(i,1,N)label[i]+=label[i-1]; up(i,1,cnt)rnk[label[step[i]]--]=i; down(i,cnt,1){ int node=rnk[i]; Right[pre[node]]+=Right[node]; } } void Go(){ now=1;int Len=0; up(i,1,(len<<1)-1){ int nxt=s[i]-‘a‘; for(;now&&(!son[now][nxt]);now=pre[now],Len=step[now]); if(!now){now=1;Len=0;} if(son[now][nxt]){now=son[now][nxt];Len++;} for(;now&&step[pre[now]]>=len;now=pre[now],Len=step[now]); if(step[pre[now]]<len&&step[now]>=len&&Len>=len){ if(flag[now]!=M+1){ ans+=Right[now]; flag[now]=M+1; } } } }}sam;namespace solution{ void Prepare(){ scanf("%s",s+1); N=strlen(s+1); up(i,1,N)sam.Extend(s[i]-‘a‘); sam.Toposort(); } void Solve(){ cin>>M; while(M--){ scanf("%s",s+1); len=strlen(s+1); up(i,1,len-1)s[i+len]=s[i]; ans=0; sam.Go(); printf("%d\n",ans); } }}int main(){ //freopen("input.in","r",stdin); using namespace solution; Prepare(); Solve(); return 0;}
Codeforces 235C. Cyclical Quest
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。