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 }

 

posted @ 2015-08-17 17:17  chenyushuo  阅读(393)  评论(0编辑  收藏  举报