1. 程式人生 > >BZOJ4556 HEOI2016字符串

BZOJ4556 HEOI2016字符串

log d+ bsp -a return str OS 後綴 b-

沒錯,又是這題,使用後綴自動機,反向建樹,主席樹維護right集合。

By:大奕哥

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 const int N=2e5+10;
  4 int rt[N],num,n,q,aa,bb,cc,dd,cnt,head[N],fa[N][19];
  5 char s[N];
  6 struct tree{
  7     int l,r;
  8 }t[N*50];
  9 void change(int &x,int l,int r,int p)
10 { 11 if(!x)x=++num; 12 if(l==r)return; 13 int mid=l+r>>1; 14 if(p>mid)change(t[x].r,mid+1,r,p); 15 else change(t[x].l,l,mid,p); 16 } 17 void merge(int &x,int y) 18 { 19 if(!x||!y){x=x+y;return;} 20 ++num;t[num]=t[x];x=num; 21 merge(t[x].l,t[y].l);
22 merge(t[x].r,t[y].r); 23 } 24 bool query(int x,int l,int r,int L,int R) 25 { 26 if(!x)return 0; 27 if(l==L&&r==R)return 1; 28 int mid=l+r>>1; 29 if(mid<L)return query(t[x].r,mid+1,r,L,R); 30 else if(mid>R)return query(t[x].l,l,mid,L,R);
31 else return query(t[x].l,l,mid,L,mid)|query(t[x].r,mid+1,r,mid+1,R); 32 } 33 struct edge{ 34 int to,nex; 35 }e[N]; 36 void addedge(int x,int y) 37 { 38 e[++cnt].to=y;e[cnt].nex=head[x];head[x]=cnt; 39 } 40 void dfs(int x) 41 { 42 for(int i=1;i<=18;++i)fa[x][i]=fa[fa[x][i-1]][i-1]; 43 for(int i=head[x];i;i=e[i].nex) 44 { 45 int y=e[i].to; 46 fa[y][0]=x;dfs(y); 47 } 48 } 49 struct SAM 50 { 51 int cnt,root,last,c[N][26],f[N],dp[N],tt[N],pos[N],p[N],r[N],id[N],l[N]; 52 SAM(){cnt=0;last=root=++cnt;} 53 void add(int x,int dd) 54 { 55 int now=last,a=++cnt;last=a;id[a]=dd; 56 l[a]=l[now]+1;p[dd]=a; 57 for(;now&&!c[now][x];now=f[now])c[now][x]=a; 58 if(!now)f[a]=root; 59 else{ 60 int q=c[now][x]; 61 if(l[q]==l[now]+1)f[a]=q; 62 else{ 63 int b=++cnt;id[b]=dd; 64 l[b]=l[now]+1; 65 f[b]=f[q]; 66 f[a]=f[q]=b; 67 memcpy(c[b],c[q],sizeof(c[q])); 68 for(;now&&c[now][x]==q;now=f[now])c[now][x]=b; 69 } 70 } 71 return; 72 } 73 void sort(){ 74 for(int i=1;i<=cnt;++i)tt[l[i]]++; 75 for(int i=1;i<=n;++i)tt[i]+=tt[i-1]; 76 for(int i=1;i<=cnt;++i)r[tt[l[i]]--]=i; 77 return; 78 } 79 bool judge(int x,int ll) 80 { 81 for(int i=18;i>=0;--i) 82 if(l[fa[x][i]]>=ll)x=fa[x][i]; 83 return query(rt[x],1,n,aa+ll-1,bb); 84 } 85 void work() 86 { 87 for(int i=cnt;i>=2;--i) 88 { 89 int x=r[i]; 90 change(rt[x],1,n,id[x]); 91 merge(rt[f[x]],rt[x]); 92 addedge(f[x],x); 93 }dfs(1);int ans=0; 94 for(int i=1;i<=q;++i) 95 { 96 97 scanf("%d%d%d%d",&aa,&bb,&cc,&dd); 98 int ll=1,rr=min(bb-aa+1,dd-cc+1);ans=0; 99 aa=n-aa+1;bb=n-bb+1;cc=n-cc+1;dd=n-dd+1; 100 swap(aa,bb);swap(cc,dd);int x=p[dd]; 101 while(ll<=rr) 102 { 103 int mid=ll+rr>>1; 104 if(judge(x,mid))ll=mid+1,ans=mid; 105 else rr=mid-1; 106 } 107 printf("%d\n",ans); 108 } 109 return; 110 } 111 }A; 112 int main() 113 { 114 scanf("%d%d",&n,&q); 115 scanf("%s",s+1); 116 reverse(s+1,s+1+n); 117 for(int i=1;i<=n;++i)A.add(s[i]-a,i); 118 A.sort();A.work(); 119 return 0; 120 }

BZOJ4556 HEOI2016字符串