【BZOJ3756】Pty的字符串(广义后缀自动机)
题意:
思路:论文题
建立Trie树的后缀自动机需要换这个长的板子
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 800010 12 #define M 8100000 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[M]; 34 int p,np,q,nq,k,cas,n; 35 int pos[N]; 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 struct sam 47 { 48 int cnt; 49 int fa[N<<1],ch[N<<1][26]; 50 int st[N<<1],b[N<<1],bl[N<<1],to[N<<1],size[N<<1]; 51 ll f[N<<1]; 52 sam() 53 { 54 cnt=1; 55 } 56 57 int add(int p,int x) 58 { 59 if(ch[p][x]) 60 { 61 q=ch[p][x]; 62 if(st[q]==st[p]+1) 63 { 64 size[q]++; 65 return q; 66 } 67 else 68 { 69 st[nq=++cnt]=st[p]+1; size[nq]=1; 70 memcpy(ch[nq],ch[q],sizeof ch[q]); 71 //t[nq]=t[q]; 72 fa[nq]=fa[q]; 73 fa[q]=nq; 74 while(ch[p][x]==q) 75 { 76 ch[p][x]=nq; 77 p=fa[p]; 78 } 79 return nq; 80 } 81 } 82 else 83 { 84 st[np=++cnt]=st[p]+1; size[np]=1; 85 while(p&&!ch[p][x]) 86 { 87 ch[p][x]=np; 88 p=fa[p]; 89 } 90 if(!p) fa[np]=1; 91 else 92 { 93 int q=ch[p][x]; 94 if(st[q]==st[p]+1) fa[np]=q; 95 else 96 { 97 nq=++cnt; st[nq]=st[p]+1; 98 memcpy(ch[nq],ch[q],sizeof ch[q]); 99 fa[nq]=fa[q]; 100 fa[q]=fa[np]=nq; 101 while(ch[p][x]==q) 102 { 103 ch[p][x]=nq; 104 p=fa[p]; 105 } 106 } 107 } 108 } 109 return np; 110 } 111 112 void solve() 113 { 114 //printf("cnt=%d\n",cnt); 115 rep(i,1,cnt) b[st[i]]++; 116 rep(i,1,cnt) b[i]+=b[i-1]; 117 rep(i,1,cnt) bl[b[st[i]]--]=i; 118 scanf("%s",s+1); 119 int n=strlen(s+1); 120 per(i,cnt,1) size[fa[bl[i]]]+=size[bl[i]]; 121 //rep(i,1,cnt) printf("%d\n",size[i]); 122 size[1]=0; 123 rep(i,1,cnt) 124 { 125 int p=bl[i]; 126 f[p]=f[fa[p]]+1ll*(st[p]-st[fa[p]])*size[p]; 127 } 128 ll ans=0; 129 p=1; 130 int L=0; 131 rep(i,1,n) 132 { 133 int x=s[i]-'a'; 134 if(ch[p][x]) L++,p=ch[p][x]; 135 else 136 { 137 while(p&&!ch[p][x]) p=fa[p]; 138 if(p) L=st[p]+1,p=ch[p][x]; 139 else L=0,p=1; 140 } 141 if(p!=1) ans+=f[fa[p]]+1ll*(L-st[fa[p]])*size[p]; 142 } 143 printf("%lld\n",ans); 144 } 145 146 }sam; 147 148 int main() 149 { 150 freopen("1.in","r",stdin); 151 freopen("1.out","w",stdout); 152 n=read(); 153 pos[1]=1; 154 rep(i,2,n) 155 { 156 int x=read(); 157 scanf("%s",s+1); 158 pos[i]=sam.add(pos[x],s[1]-'a'); 159 } 160 sam.solve(); 161 return 0; 162 }
null