标签:bzoj2555 substring 后缀自动机 link-cut-tree 暴力
转载请注明出处:http://blog.csdn.net/vmurder/article/details/42915143
题解:正解是LCT+SAM。
但是出题人太神以至于不屑于卡你,所以只写个SAM然后暴力维护就好了。
这样虽然很不科学,但是可以比正解快三倍。
我是太困了吧,写挂了调了好久(发呆了好久然后秒调过,或者说半眯着眼睛睡了一会)
代码:
<span style="font-family:KaiTi_GB2312;font-size:18px;">#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define N 1601000 #define T 26 #define inf 0x3f3f3f3f using namespace std; int m; char s[N],opt[10]; struct SAM { int next[N][T],pa[N],deep[N],size[N]; int cnt,last,root; int newnode(int _dep){deep[++cnt]=_dep;return cnt;} void init() { last=root=cnt=1; } void add(int alp) { int p=newnode(deep[last]+1); int u=last; while(u&&!next[u][alp])next[u][alp]=p,u=pa[u]; if(!u)pa[p]=root; else { int v=next[u][alp]; if(deep[v]==deep[u]+1)pa[p]=v; else { int nv=newnode(deep[u]+1); pa[nv]=pa[v]; pa[v]=pa[p]=nv; size[nv]=size[v]; memcpy(next[nv],next[v],sizeof next[nv]); while(u&&next[u][alp]==v)next[u][alp]=nv,u=pa[u]; } } last=p; for(;p != root;p=pa[p])size[p]++; } int query() { int i,x=root,alp; for(i=0;s[i];i++) if(next[x][alp=s[i]-'A']) x=next[x][alp]; else return 0; return size[x]; } }sam; inline void DecodeWithMask(int mask) { int length = strlen(s); for(int i = 0; i < length; ++i) { mask = (mask * 131 + i) % length; swap(s[i],s[mask]); } } int main() { freopen("test.in","r",stdin); int i,j,k; scanf("%d%s",&m,s); sam.init(); for(i=0;s[i];i++)sam.add(s[i]-'A'); int mask=0; while(m--) { scanf("%s%s",opt,s); DecodeWithMask(mask); if(opt[0]=='Q'){ int last_ans=sam.query(); printf("%d\n",last_ans); mask^=last_ans; } else {for(i=0;s[i];i++)sam.add(s[i]-'A');} } return 0; } </span>
标签:bzoj2555 substring 后缀自动机 link-cut-tree 暴力
原文地址:http://blog.csdn.net/vmurder/article/details/42915143