如果直接用后缀树的话,就得建出来然后跑虚树什么的了,很麻烦
但是用后缀数组可以规约到一类问题里面http://www.cnblogs.com/hehe54321/p/8666859.html
每次询问一个集合的话,只需要把有关的内容抽离出来就好了
为什么比别人的后缀树+虚树还要长啊
错误记录:拖板子忘了改49行的数据范围(1000000没改成500000)
1 #include<iostream> 2 #include<algorithm> 3 #include<string> 4 #define md 23333333333333333 5 using namespace std; 6 typedef long long LL; 7 string txt; 8 namespace SA 9 { 10 int n,p,m=128,sa[500100],t1[500100],t2[500100],cnt[500100],*x=t1,*y=t2; 11 int *height=t2,*rk=t1; 12 int st[500100][21],log2x[500100],lft[21]; 13 const int log2n=20; 14 void build() 15 { 16 int i,k; 17 n=txt.length(); 18 for(i=0;i<n;i++) cnt[x[i]=txt[i]]++; 19 for(i=1;i<m;i++) cnt[i]+=cnt[i-1]; 20 for(i=n-1;i>=0;i--) sa[--cnt[x[i]]]=i; 21 for(k=1;k<=n;k<<=1) 22 { 23 p=0; 24 for(i=n-k;i<n;i++) y[p++]=i; 25 for(i=0;i<n;i++) if(sa[i]>=k) y[p++]=sa[i]-k; 26 for(i=0;i<m;i++) cnt[i]=0; 27 for(i=0;i<n;i++) cnt[x[y[i]]]++; 28 for(i=1;i<m;i++) cnt[i]+=cnt[i-1]; 29 for(i=n-1;i>=0;i--) sa[--cnt[x[y[i]]]]=y[i]; 30 swap(x,y);p=0; 31 x[sa[0]]=0; 32 for(i=1;i<n;i++) 33 x[sa[i]]=y[sa[i]]==y[sa[i-1]] 34 &&(sa[i]+k<n?y[sa[i]+k]:0)==(sa[i-1]+k<n?y[sa[i-1]+k]:0) 35 ?p:++p; 36 if(p>=n) break; 37 m=p+1; 38 } 39 for(i=0;i<n;i++) rk[sa[i]]=i; 40 for(i=0,k=0;i<n;i++) 41 { 42 if(k) k--; 43 if(rk[i]) 44 while(sa[rk[i]-1]+k<n&&i+k<n&&txt[sa[rk[i]-1]+k]==txt[i+k]) k++; 45 height[rk[i]]=k; 46 } 47 lft[0]=1;for(i=1;i<=log2n;i++) lft[i]=lft[i-1]<<1; 48 log2x[1]=k=0; 49 for(i=2;i<=500000;i++) 50 { 51 if(i>=lft[k+1]) ++k; 52 log2x[i]=k; 53 } 54 for(i=0;i<n;i++) st[i][0]=height[i]; 55 for(k=1;k<=log2n;k++) 56 for(i=0;i<n-lft[k]+1;i++) 57 st[i][k]=min(st[i][k-1],st[i+lft[k-1]][k-1]); 58 } 59 int lcp(int l,int r) 60 { 61 //if(l==r) return n-l; 62 //l=rk[l];r=rk[r]; 63 if(l>r) swap(l,r); 64 l++;int k=log2x[r-l+1]; 65 return min(st[l][k],st[r-lft[k]+1][k]); 66 } 67 } 68 struct Info 69 { 70 int pos,dep; 71 Info(int a,int b):pos(a),dep(b){} 72 Info():pos(0),dep(0){} 73 }b[3000100]; 74 bool operator<(const Info& a,const Info& b) 75 { 76 return a.dep>b.dep; 77 } 78 int n,m,num,a[3000100],sz[3000100],fa[3000100];LL ans; 79 int find(int x) {return x==fa[x]?x:fa[x]=find(fa[x]);} 80 int main() 81 { 82 ios::sync_with_stdio(0); 83 int i,d,t,fx,fy; 84 cin>>n>>m;cin>>txt; 85 SA::build(); 86 while(m--) 87 { 88 cin>>num; 89 for(i=1;i<=num;i++) cin>>a[i],a[i]=SA::rk[a[i]-1]; 90 sort(a+1,a+num+1);num=unique(a+1,a+num+1)-a-1; 91 if(num<=1) {cout<<0<<' ';continue;} 92 for(i=2;i<=num;i++) b[i]=Info(i,SA::lcp(a[i],a[i-1])); 93 for(i=1;i<=num;i++) fa[i]=i,sz[i]=1; 94 sort(b+2,b+num+1);ans=0; 95 for(i=2;i<=num;i++) 96 { 97 d=b[i].dep;t=b[i].pos; 98 fx=find(t-1);fy=find(t); 99 ans=(ans+(LL)d*sz[fx]*sz[fy])%md; 100 sz[fy]+=sz[fx];fa[fx]=fy; 101 } 102 cout<<ans<<' '; 103 } 104 return 0; 105 }