QOJ.ac

QOJ

IDSubmission IDProblemHackerOwnerResultSubmit timeJudge time
#594#389509#7742. Suffix StructureFlamirezhaohaikunSuccess!2024-04-14 14:55:342024-04-14 14:55:35

Details

Extra Test:

Time Limit Exceeded

input:

1
200000 200000
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 ...

output:


result:


IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#389509#7742. Suffix StructurezhaohaikunTL 310ms97352kbC++203.1kb2024-04-14 14:49:512024-04-14 14:58:36

answer

#include<bits/stdc++.h>
#define ll long long
#define ull unsigned long long
using namespace std;
const int N=3e5+10,B=1e9+7;
int c[N],ti[N];
int h[N],nex[N],to[N],tot;
int f[N][21],dep[N];
int gl[N],gf[N];
ull hs[N],pw[N],hst[N];
ll cf[N],cf2[N];
int tp[N],ct;
struct tree{
  map<int,int>ch;
  int pt;
  ll ts;
}t[N];
unordered_map<ull,int>mp;
ll ans[N];
int n,m;
int T;
void add(int x,int y){to[++tot]=y,nex[tot]=h[x],h[x]=tot;}
void dfs(int u){
  for(int i=h[u];i;i=nex[i]){
    int v=to[i];
    dep[v]=dep[u]+1;
    hs[v]=1ull*hs[u]*B+c[v];
    if(!t[u].ch.count(c[v])){
      t[u].ch[c[v]]=v;
      mp[hs[v]]=v;
    }
    dfs(v);
  }
}
void getfail(){
  t[0].pt=-1;
  queue<int>q;
  for(auto i:t[0].ch)q.push(i.second);
  while(!q.empty()){
    int u=q.front();q.pop();
    tp[++ct]=u;
    for(auto i:t[u].ch){
      int pt;
      for(pt=t[u].pt;pt!=-1&&!t[pt].ch.count(i.first);pt=t[pt].pt);
      if(pt!=-1)t[i.second].pt=t[pt].ch[i.first];
      q.push(i.second);
    }
  }
}
ull mghs(int x,int l){
  return hs[x]*pw[l]+hst[l];
}
bool check(int x,int mid){
  if(mp.count(mghs(x,mid)))return 1;
  return 0;
}
int get(int x){
  int l=0,r=m,ans=0;
  while(l<=r){
    int mid=l+r>>1;
    if(check(x,mid))l=mid+1,ans=mid;
    else r=mid-1;
  }
  return mp[mghs(x,ans)];
}
int kthf(int x,int y){
  for(int i=20;i>=0;i--)
    if(y-(1<<i)>=0)x=f[x][i],y-=(1<<i);
  return x;
}
void calc(){
  int pt=0;
  for(int i=1;i<=m;i++){
    while(pt!=-1&&!t[pt].ch.count(ti[i]))pt=t[pt].pt;
    if(pt!=-1){
      pt=t[pt].ch[ti[i]];
      ans[i]+=cf[i]*dep[pt];
    }
    else pt=0;
  }
}
#define mem(arr,x) for(int i=0;i<=(x);i++)arr[i]=0;
void clear(){
  ct=tot=0;
  mem(c,n);mem(h,n);
  for(int i=0;i<=n;i++){
    for(int j=0;j<=20;j++)
      f[i][j]=0;
    t[i].ch.clear();
    t[i].pt=t[i].ts=0;
  }
  mem(cf,m);mem(cf2,m);
  mem(ans,m);mp.clear();
  mem(tp,n);mem(dep,n);
}
void work(){
  cin>>n>>m;
  clear();
  pw[0]=1;
  for(int i=1;i<=n;i++)pw[i]=1ull*pw[i-1]*B;
  for(int i=1;i<=n;i++)cin>>f[i][0],add(f[i][0],i);
  for(int j=1;j<=20;j++)
    for(int i=1;i<=n;i++)
      f[i][j]=f[f[i][j-1]][j-1];
  for(int i=1;i<=n;i++)cin>>c[i];
  dfs(0);
  for(int i=1;i<=m;i++)cin>>ti[i];
  for(int i=1;i<=m;i++)hst[i]=1ull*hst[i-1]*B+ti[i];
  getfail();
  for(int i=1;i<=n;i++)t[i].ts=1;
  for(int j=n;j>=1;j--){
    int i=tp[j];
    int p=get(i);
    int nxt=t[p].pt,bdep=dep[p]-dep[i],r=bdep;
    int kf=kthf(nxt,bdep),ct=t[i].ts;
    t[kf].ts+=t[i].ts;
    if(dep[nxt]>=bdep){
      ans[1]+=ct*(dep[i]-dep[kf]);
      ans[r+1]-=ct*(dep[i]-dep[kf]);
    }
    else{
      int x=dep[i]+1;
      cf[1]-=ct,cf[r+1]+=ct;
      cf2[1]+=x*ct,cf2[2]-=(x-1)*ct;
      cf2[r+1]-=(x+r)*ct,cf2[r+2]+=(x+r-1)*ct;
    }
  }
  cf[1]+=t[0].ts;
  for(int i=1;i<=m;i++)cf2[i]+=cf2[i-1];
  for(int i=1;i<=m;i++)cf2[i]+=cf2[i-1],cf[i]+=cf[i-1],ans[i]+=ans[i-1];
  for(int i=1;i<=m;i++)ans[i]+=cf2[i];
  calc();
  for(int i=1;i<=m;i++)cout<<ans[i]<<' ';
  cout<<'\n';
}
signed main(){
  ios::sync_with_stdio(0);
  cin.tie(0),cout.tie(0);
  cin>>T;
  while(T--)work();
  return 0;
}