bzoj2534: Uva10829L-gap字符串
Description
有一种形如uvu形式的字符串,其中u是非空字符串,且V的长度正好为L,那么称这个字符串为L-Gap字符串
给出一个字符串S,以及一个正整数L,问S中有多少个L-Gap子串.
Input
第一行一个数字L
第二行一个字符串S
Output
一个数字表示S中有多少个L-Gap子串.
Sample Input
3
aabbaa
Sample Output
2
Hint
S的长度不超过50000,L<=10
题解:http://www.cnblogs.com/iamCYY/p/4730777.html
Orz CYY
code:
1 #include<cstdio> 2 #include<iostream> 3 #include<cmath> 4 #include<cstring> 5 #include<algorithm> 6 #define maxn 50050 7 using namespace std; 8 char ch,s[maxn]; 9 int n,l,ans; 10 int fa[maxn],root[maxn],list[maxn],cnt,que[maxn]; 11 int SA[maxn],rank[maxn],height[maxn],sum[maxn],t1[maxn],t2[maxn]; 12 int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);} 13 struct Splay{ 14 int tot,son[maxn][2],fa[maxn],siz[maxn],val[maxn]; 15 void init(){ 16 for (int i=1;i<=n;i++) siz[++tot]=1; 17 for (int i=1;i<=n;i++) val[i]=SA[i]; 18 } 19 int which(int x){return son[fa[x]][1]==x;} 20 void update(int x){siz[x]=siz[son[x][0]]+siz[son[x][1]]+1;} 21 void rotate(int x){ 22 int y=fa[x],d=which(x),dd=which(y); 23 fa[son[x][d^1]]=y,son[y][d]=son[x][d^1],fa[x]=fa[y]; 24 if (fa[x]) son[fa[x]][dd]=x; 25 son[x][d^1]=y,fa[y]=x,update(y),update(x); 26 } 27 void splay(int x){ 28 while (fa[x]){ 29 if (!fa[fa[x]]) rotate(x); 30 else if (which(x)==which(fa[x])) rotate(fa[x]),rotate(x); 31 else rotate(x),rotate(x); 32 } 33 root[find(x)]=x; 34 } 35 void insert(int root,int x){ 36 int f,t; 37 for (f=t=root;t;t=son[t][val[x]>val[t]]) f=t; 38 son[f][val[x]>val[f]]=x,fa[x]=f,splay(x); 39 } 40 void merge(int x){while (cnt) insert(root[x],que[cnt--]);} 41 int find_pre(int root,int v){ 42 int x,t=0; 43 for (x=root;x;val[x]<v?t=x,x=son[x][1]:x=son[x][0]); 44 if (t) splay(t); 45 return t?siz[son[t][0]]+1:0; 46 } 47 int find_next(int root,int v){ 48 int x,t=0; 49 for (x=root;x;val[x]>v?t=x,x=son[x][0]:x=son[x][1]); 50 if (t) splay(t); 51 return t?siz[son[t][1]]+1:0; 52 } 53 void get(int x){ 54 if (son[x][0]) get(son[x][0]); 55 que[++cnt]=x; 56 if (son[x][1]) get(son[x][1]); 57 son[x][0]=son[x][1]=fa[x]=0; 58 } 59 }T; 60 bool ok; 61 void read(int &x){ 62 for (ok=0,ch=getchar();!isdigit(ch);ch=getchar()) if (ch=='-') ok=1; 63 for (x=0;isdigit(ch);x=x*10+ch-'0',ch=getchar()); 64 if (ok) x=-x; 65 } 66 bool cmp(int x,int y){ 67 if (height[x]!=height[y]) return height[x]>height[y]; 68 return x<y; 69 } 70 void get_SA(){ 71 int *x=t1,*y=t2,m=255,tot=0; 72 for (int i=1;i<=n;i++) sum[x[i]=s[i]]++; 73 for (int i=1;i<=m;i++) sum[i]+=sum[i-1]; 74 for (int i=n;i>=1;i--) SA[sum[x[i]]--]=i; 75 for (int len=1;tot<n;len<<=1,m=tot){ 76 tot=0; 77 for (int i=n-len+1;i<=n;i++) y[++tot]=i; 78 for (int i=1;i<=n;i++) if (SA[i]>len) y[++tot]=SA[i]-len; 79 for (int i=1;i<=m;i++) sum[i]=0; 80 for (int i=1;i<=n;i++) sum[x[y[i]]]++; 81 for (int i=1;i<=m;i++) sum[i]+=sum[i-1]; 82 for (int i=n;i>=1;i--) SA[sum[x[y[i]]]--]=y[i]; 83 swap(x,y),x[SA[1]]=tot=1; 84 for (int i=2;i<=n;i++){ 85 if (y[SA[i]]!=y[SA[i-1]]||y[SA[i]+len]!=y[SA[i-1]+len]) tot++; 86 x[SA[i]]=tot; 87 } 88 } 89 for (int i=1;i<=n;i++) rank[i]=x[i]; 90 } 91 void get_height(){ 92 for (int i=1,j=0;i<=n;i++){ 93 if (rank[i]==1) continue; 94 while (s[i+j]==s[SA[rank[i]-1]+j]) j++; 95 height[rank[i]]=j; 96 if (j>0) j--; 97 } 98 } 99 int main(){ 100 read(l),scanf("%s",s+1),n=strlen(s+1); 101 get_SA(),get_height(),T.init(); 102 for (int i=1;i<=n;i++) root[i]=i; 103 for (int i=1;i<=n;i++) fa[i]=i; 104 for (int i=1;i<n;i++) list[i]=i+1; 105 sort(list+1,list+n,cmp); 106 for (int i=1;i<n;i++){ 107 int x=find(list[i]-1),y=find(list[i]),lcp=height[list[i]]; cnt=0; 108 if (T.siz[root[x]]>T.siz[root[y]]) swap(x,y); 109 int tsiz=T.siz[root[y]]; 110 T.get(root[x]); 111 for (int j=1,t=que[j];j<=cnt;j++,t=que[j]){ 112 ans+=T.find_next(root[y],SA[t]+l); 113 ans+=T.find_pre(root[y],lcp+SA[t]+l+1)-tsiz; 114 ans+=T.find_next(root[y],SA[t]-lcp-l-1); 115 ans+=T.find_pre(root[y],SA[t]-l)-tsiz; 116 } 117 fa[x]=y,T.merge(y); 118 } 119 printf("%d\n",ans); 120 return 0; 121 }