bzoj1396&&2865 识别子串 后缀自动机+线段树

Input

一行,一个由小写字母组成的字符串S,长度不超过10^5

Output

L行,每行一个整数,第i行的数据表示关于S的第i个元素的最短识别子串有多长.

Sample Input

agoodcookcooksgoodfood

Sample Output

1
2
3
3
2
2
3
3
2
2
3
3
2
1
2
3
3
2
1
2
3
4
 
出现只有一次的是parent数上的叶子节点,endpos=1
所以只需要找endpos=1的节点minlen-maxlen之间对于一段的贡献放向去思考就可以了。
 

理解起来就是对于[endposmaxlen+1,endposminlen+1][endpos−maxlen+1,endpos−minlen+1]中的每个子串都是单独存在的,所以这个RightRight集合贡献给他的答案就是这个点到endposendpos的长度。

对于[endposminlen,endpos][endpos−minlen,endpos]中的每个位置xx,贡献就是minlenminlen;

理解起来就是对于[endposminlen,endpos][endpos−minlen,endpos]中的每个子串显然是存在多个结束位置的,所以当前这个RightRight集合能够贡献给他的符合只出现一次且最短的,就是刚好跨过它的最小,即minlenminlen。

 

对于2865数据范围大了,而且还卡内存,不要面孔

 

纯自己手打

  1 #pragma GCC optimize(2)
  2 #pragma G++ optimize(2)
  3 #include<cstring>
  4 #include<cmath>
  5 #include<iostream>
  6 #include<algorithm>
  7 #include<cstdio>
  8 
  9 #define inf 1000000007
 10 #define N 200007
 11 using namespace std;
 12 inline int read()
 13 {
 14     int x=0,f=1;char ch=getchar();
 15     while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
 16     while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
 17     return x*f;
 18 }
 19 
 20 int n;
 21 char ch[N];
 22 
 23 struct segment_tree
 24 {
 25     int tree[N<<2];
 26     inline void push_down(int p,int l,int r)
 27     {
 28         if(l==r)return;
 29         int ls=p<<1,rs=p<<1|1;
 30         tree[ls]=min(tree[ls],tree[p]);
 31         tree[rs]=min(tree[rs],tree[p]);
 32     }
 33     void update(int p,int l,int r,int x,int y,int num)
 34     {
 35         if(x>y)return;
 36         push_down(p,l,r);
 37         if(l==x&&y==r)
 38         {
 39             tree[p]=min(tree[p],num);
 40             return;
 41         }
 42         int mid=(l+r)>>1;
 43         if(y<=mid)update(p<<1,l,mid,x,y,num);
 44         else if(x>mid)update(p<<1|1,mid+1,r,x,y,num);
 45         else update(p<<1,l,mid,x,mid,num),update(p<<1|1,mid+1,r,mid+1,y,num);
 46     }
 47     void build(int p,int l,int r)
 48     {
 49         if(l==r)
 50         {
 51             tree[p]=inf;
 52             return;
 53         }
 54         int mid=(l+r)>>1;
 55         build(p<<1,l,mid),build(p<<1|1,mid+1,r);
 56         tree[p]=inf;
 57     }
 58     int query(int p,int l,int r,int x)
 59     {
 60         push_down(p,l,r);
 61         if(l==r)return tree[p];
 62         int mid=(l+r)>>1;
 63         if(x<=mid) return query(p<<1,l,mid,x);
 64         else return query(p<<1|1,mid+1,r,x);
 65     }
 66 }A,B;
 67 struct sam
 68 {
 69     int last,cnt,rt;
 70     int fa[N],mx[N],c[N][26];
 71     sam(){last=cnt=rt=1;}
 72     void extend(int x)
 73     {
 74         int p=last,np=last=++cnt;mx[np]=mx[p]+1;
 75         while(p&&!c[p][x])
 76         {
 77             c[p][x]=np;
 78             p=fa[p];
 79         }
 80         if(!p)fa[np]=rt;
 81         else
 82         {
 83             int q=c[p][x];
 84             if(mx[q]==mx[p]+1)fa[np]=q;
 85             else
 86             {
 87                 int nq=++cnt;mx[nq]=mx[p]+1;
 88                 memcpy(c[nq],c[q],sizeof(c[q]));
 89                 fa[nq]=fa[q];
 90                 fa[q]=fa[np]=nq;
 91                 while(c[p][x]==q)c[p][x]=nq,p=fa[p];
 92             }
 93         }
 94     }
 95     bool flag[N];
 96     void build()
 97     {
 98         memset(flag,true,sizeof(flag));
 99         for (int i=1;i<=cnt;i++)
100             flag[fa[i]]=false;
101         for (int i=1;i<=cnt;i++)
102             if(flag[i])
103             {
104                 int l=mx[i]-mx[fa[i]],r=mx[i];
105                 A.update(1,1,n,1,l-1,r+1);
106                 B.update(1,1,n,l,r,r-l+1);
107             }
108     }
109 }sam;
110 void solve()
111 {
112     for (int i=1;i<=n;i++)
113         printf("%d\n",min(A.query(1,1,n,i)-i,B.query(1,1,n,i)));
114 }
115 int main()
116 {
117     freopen("fzy.in","r",stdin);
118     freopen("fzy.out","w",stdout);
119     scanf("%s",ch+1);n=strlen(ch+1);
120     for (int i=1;i<=n;i++)
121         sam.extend(ch[i]-'a');
122     A.build(1,1,n),B.build(1,1,n);
123 //    cout<<1<<endl<<endl;
124     sam.build(),solve();
125 }

 

posted @ 2018-03-08 20:34  Kaiser-  阅读(158)  评论(0编辑  收藏  举报