【BZOJ1396】识别子串(后缀自动机,线段树)

题意:

 

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

思路:论文题

 

 设p为自动机上的合法结点,r为右端点,len=st[fa[p]]]+1

位置[r-st[p]+1,r-len+1]与r-i+1取min,其中i为下标

位置[r-len+1,r]与len取min

建立两棵线段树,分别维护r+1和len

因为只有区间修改和单点查询可以不写lazytag

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 typedef long long ll;
  4 typedef unsigned int uint;
  5 typedef unsigned long long ull;
  6 typedef pair<int,int> PII;
  7 typedef pair<ll,ll> Pll;
  8 typedef vector<int> VI;
  9 typedef vector<PII> VII;
 10 typedef pair<ll,int>P;
 11 #define N  100010
 12 #define M  210000
 13 #define fi first
 14 #define se second
 15 #define MP make_pair
 16 #define pi acos(-1)
 17 #define mem(a,b) memset(a,b,sizeof(a))
 18 #define rep(i,a,b) for(int i=(int)a;i<=(int)b;i++)
 19 #define per(i,a,b) for(int i=(int)a;i>=(int)b;i--)
 20 #define lowbit(x) x&(-x)
 21 #define Rand (rand()*(1<<16)+rand())
 22 #define id(x) ((x)<=B?(x):m-n/(x)+1)
 23 #define ls p<<1
 24 #define rs p<<1|1
 25 
 26 const int MOD=1e9+7,inv2=(MOD+1)/2;
 27       double eps=1e-6;
 28       int INF=1e9;
 29       ll inf=5e13;
 30       int dx[4]={-1,1,0,0};
 31       int dy[4]={0,0,-1,1};
 32 
 33 char s[N];
 34 int p,np,q,nq,k,cas,n;
 35 int t[N<<2][2];
 36 
 37 int read()
 38 {
 39    int v=0,f=1;
 40    char c=getchar();
 41    while(c<48||57<c) {if(c=='-') f=-1; c=getchar();}
 42    while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar();
 43    return v*f;
 44 }
 45 
 46 void build(int l,int r,int p,int op)
 47 {
 48     t[p][op]=INF;
 49     if(l==r) return;
 50     int mid=(l+r)>>1;
 51     build(l,mid,ls,op);
 52     build(mid+1,r,rs,op);
 53 }
 54 
 55 void update(int l,int r,int x,int y,int v,int p,int op)
 56 {
 57     if(x<=l&&r<=y)
 58     {
 59         t[p][op]=min(t[p][op],v);
 60         return;
 61     }
 62     int mid=(l+r)>>1;
 63     if(x<=mid) update(l,mid,x,y,v,ls,op);
 64     if(y>mid) update(mid+1,r,x,y,v,rs,op);
 65 }
 66 
 67 int query(int l,int r,int x,int p,int op)
 68 {
 69     if(l==r) return t[p][op];
 70     int mid=(l+r)>>1;
 71     if(x<=mid) return min(t[p][op],query(l,mid,x,ls,op));
 72      else return min(t[p][op],query(mid+1,r,x,rs,op));
 73 }
 74 
 75 struct sam
 76 {
 77     int cnt;
 78     int fa[N<<1],ch[N<<1][26];
 79     int st[N<<1],b[N<<1],bl[N<<1],to[N<<1],size[N<<1];
 80 
 81     sam()
 82     {
 83         cnt=np=1;
 84     }
 85 
 86     void add(int x,int i)
 87     {
 88         p=np; st[np=++cnt]=st[p]+1;
 89         to[np]=i;
 90         while(p&&!ch[p][x])
 91         {
 92             ch[p][x]=np;
 93             p=fa[p];
 94         }
 95         if(!p) fa[np]=1;
 96          else if(st[p]+1==st[q=ch[p][x]]) fa[np]=q;
 97           else
 98           {
 99                   st[nq=++cnt]=st[p]+1;
100                   memcpy(ch[nq],ch[q],sizeof ch[q]);
101                   //t[nq]=t[q];
102                   fa[nq]=fa[q];
103                   fa[q]=fa[np]=nq;
104                   while(p&&ch[p][x]==q)
105                   {
106                       ch[p][x]=nq;
107                       p=fa[p];
108                   }
109           }
110     }
111 
112     void solve()
113     {
114         rep(i,1,cnt) b[st[i]]++;
115         rep(i,1,cnt) b[i]+=b[i-1];
116         rep(i,1,cnt) bl[b[st[i]]--]=i;
117         int u=1;
118         rep(i,1,n)
119         {
120             u=ch[u][s[i]-'a'];
121             size[u]++;
122         }
123         build(1,n,1,0);
124         build(1,n,1,1);
125         per(i,cnt,1) size[fa[bl[i]]]+=size[bl[i]];
126 
127         rep(i,1,cnt)
128         {
129             int p=bl[i];
130             if(size[p]>1) continue;
131             int len=st[fa[p]]+1,r=to[p];
132             update(1,n,r-len+1,r,len,1,0);
133             update(1,n,r-st[p]+1,r-len+1,r+1,1,1);
134         }
135 
136         rep(i,1,n)
137         {
138             int t1=query(1,n,i,1,0),t2=-i+query(1,n,i,1,1);
139             printf("%d\n",min(t1,t2));
140         }
141 
142     }
143 }sam;
144 
145 
146 int main()
147 {
148     scanf("%s",s+1);
149     n=strlen(s+1);
150     rep(i,1,n) sam.add(s[i]-'a',i);
151     sam.solve();
152     return 0;
153 }

 

posted on 2019-09-11 17:27  myx12345  阅读(181)  评论(0编辑  收藏  举报

导航