# [ BZOJ 3879 ] SvT

$\\$

## Description

$\sum_{i,j\in [1,t]，i\not =j} lcp(suf(x_i),suf(x_j))$

• $n\le 5\times 10^5,\sum t\le 3\times 10^6$

$\\$

## Solution

$lcp(i,j)$ 表示 $suf(i),suf(j)$ 的最长公共前缀长度，设 $LCP(i,j)$ 表示 $lcp(sa[i],sa[j])$

$\\$

$\\$

## Code

#include<cmath>
#include<cctype>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define N 500010
#define M 3000010
#define R register
#define gc getchar
#define mod 23333333333333333ll
using namespace std;
typedef long long ll;

inline ll rd(){
ll x=0; bool f=0; char c=gc();
while(!isdigit(c)){if(c=='-')f=1;c=gc();}
while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=gc();}
return f?-x:x;
}

ll n,m,s[N],sa[N],t1[N],t2[N],rk[N],h[N],cnt[N];

inline void da(ll n,ll m){
s[n++]=0;
ll *x=t1,*y=t2;
for(R ll i=0;i<n;++i) ++cnt[x[i]=s[i]];
for(R ll i=1;i<m;++i) cnt[i]+=cnt[i-1];
for(R ll i=n-1;~i;--i) sa[--cnt[x[i]]]=i;
for(R ll k=1,p=0;p<n&&k<=n;k<<=1,m=p){
p=0;
for(R ll i=n-k;i<n;++i) y[p++]=i;
for(R ll i=0;i<n;++i) if(sa[i]>=k) y[p++]=sa[i]-k;
for(R ll i=0;i<m;++i) cnt[i]=0;
for(R ll i=0;i<n;++i) ++cnt[x[y[i]]];
for(R ll i=1;i<m;++i) cnt[i]+=cnt[i-1];
for(R ll i=n-1;~i;--i) sa[--cnt[x[y[i]]]]=y[i];
swap(x,y); p=1; x[sa[0]]=0;
for(R ll i=1;i<n;++i)
x[sa[i]]=(y[sa[i]]==y[sa[i-1]]&&y[sa[i-1]+k]==y[sa[i]+k])?p-1:p++;
}
--n; h[0]=0;
for(R ll i=0;i<n;++i) sa[i]=sa[i+1];
for(R ll i=0;i<n;++i) rk[sa[i]]=i;
for(R ll i=0,p=0;i<n;++i){
if(!rk[i]) continue;
if(p) --p;
while(s[i+p]==s[sa[rk[i]-1]+p]) ++p;
h[rk[i]]=p;
}
}

struct ST{
ll c[N][20];
inline void reset(){
for(R ll i=0;i<n;++i) c[i][0]=h[i];
for(R ll k=1;(1ll<<k)<=n;++k)
for(R ll i=0;i<n-k;++i) c[i][k]=min(c[i][k-1],c[i+(1ll<<(k-1))][k-1]);
}
inline ll query(ll l,ll r){
ll t=log2(r-l+1);
return min(c[l][t],c[r-(1ll<<t)+1][t]);
}
}st;

ll c[M],sum,top;

struct S{int x,cnt;}stk[M];

inline bool cmp(ll x,ll y){return rk[x]<rk[y];}

inline void work(){
ll t=rd(),res=0;
for(R int i=1;i<=t;++i) c[i]=rd()-1;
sort(c+1,c+1+t);
for(R int i=1,tmp=0;i<=t;++i){
c[++tmp]=c[i];
while(c[i+1]==c[i]&&i<=t) ++i;
if(i==t){t=tmp;break;}
}
if(t<=1){puts("0");return;}
sort(c+1,c+1+t,cmp);
sum=top=0;
for(R ll i=1,now,cnt=1;i<t;++i,cnt=1){
now=st.query(rk[c[i]]+1,rk[c[i+1]]);
while(top&&stk[top].x>=now){
cnt+=stk[top].cnt;
sum-=stk[top].cnt*stk[top].x;
--top;
}
stk[++top].x=now;
stk[top].cnt=cnt;
(sum+=stk[top].x*stk[top].cnt)%=mod;
(res+=sum)%=mod;
}
printf("%lld\n",res);
}

int main(){
n=rd(); m=rd();
char c=gc(); while(!isalpha(c)) c=gc();
s[0]=c-' ';
for(R ll i=2;i<=n;++i) s[i-1]=gc()-' ';
da(n,256); st.reset();
while(m--) work();
return 0;
}


posted @ 2018-11-20 17:22  SGCollin  阅读(154)  评论(0编辑  收藏  举报