Main topic:
Given a number of matching strings, to create a string of not more than L, each matching string has its own value, the matching string each occurrence in the string will contribute a value ... The maximum value that may be obtained.
Total length of matched string not exceeding 200,l<=10^14, time limit 6s
Typical multiplication Floyd ... Look at the data range and you probably know what it is. = =
The words of the violent wording. To build an AC automaton, the value of each node is the sum of the value of the matched string of the end node on its fail chain. Then in the above violent DP. F[I][J] represents the maximum value that can be obtained from the I-node and the J-step.
This form is identical to the Usaco "cow relay Run" ...
F[i][j][k] means starting from the I node, walking 2^j step, reaching the maximum value of K. Fa[i][j][k]: Starting from the K-node, walk 2^j step, can reach I.
f[i][j][k]=max{F[i][j-1][k1]+f[k1][j-1][k]}, (Fa[k1][j-1][i] and Fa[k][j-1][k1] True
After the F is found, it is as fast as the power of the posture of the L split into a number of two Zhizi, and then the corresponding F array together (recorded as G).
The final answer is max{G[0][i]}, (I is the node on the automaton.)
Time complexity O (N^3*LOGL): CF evaluation Maggie Fast. Only ran the 1200+ms.
1#include <cstdio>2#include <iostream>3#include <cstring>4#include <algorithm>5#include <bitset>6 #definell Long Long7 #defineull unsigned long Long8 #defineD Double9 using namespacestd;Ten Const intmaxn=203; One Constll inf= (1ll<< +)-1ll; A intch[maxn][ -],next[maxn][ -],tot; - intDL[MAXN],FAIL[MAXN],VAL[MAXN],V[MAXN]; -ll f[maxn][ A][maxn],g[maxn][2][MAXN]; thebitset<maxn>fa[maxn][ A]; - CharS[MAXN]; - - intI,j,k,n,m,now,pre; + ll L; - BOOLfirst=1; + A at intRA,FH;CharRx; -InlineintRead () { -Rx=getchar (), ra=0, fh=1; - while(rx!='-'&& (rx<'0'|| Rx>'9')) rx=GetChar (); - if(rx=='-') fh=-1, rx=GetChar (); - while(rx>='0'&&rx<='9') ra*=Ten, ra+=rx- -, Rx=getchar ();returnra*fh; in } -InlinevoidUPD (ll &a,ll b) {if(a<b) a=b;} to + voidTrieintNintv) { - intp=0; the for(intI=1; i<=n;i++){ *s[i]-='a'; $ if(!ch[p][s[i]]) ch[p][s[i]]=++tot,p=tot;Panax Notoginseng Elsep=Ch[p][s[i]]; - } theVal[p]+=v;//printf ("ggpos:%d\n", p); + } A voidGetfail () { the intL=0, r=1, i,now,j,p;dl[1]=0; + while(l<R) { -now=dl[++l]; $ for(i=0;i< -; i++)if(Ch[now][i]) { $j=ch[now][i],dl[++r]=j,next[now][i]=J; - for(P=fail[now];p &&!ch[p][i];p =fail[p]); - if(!now) fail[j]=0;Elsefail[j]=Ch[p][i]; theVAL[J]+=VAL[FAIL[J]];//printf ("%d---->%d val:%d\n", J,fail[j],val[j]); -}Else{Wuyi for(P=fail[now];p &&!ch[p][i];p =fail[p]); thenext[now][i]=Ch[p][i]; - } Wu } - } About $InlinevoidRUN_FA (intj) { - intI,K1;//printf ("j:%d\n", j); - for(i=0; i<=tot;i++) for(k1=0; k1<=tot;k1++) - if(fa[i][j-1][K1]) fa[i][j]|=fa[k1][j-1]; A //for (i=0;i<=tot;i++) for (k1=0;k1<=tot;k1++) if (Fa[i][j][k1]) printf ("%d->%d\n", k1,i); + } theInlinevoidRun_f (intj) { - intI,k;registerintK1;//printf ("j:%d\n", j); $ for(i=0; i<=tot;i++) for(k=0; k<=tot;k++)if(Fa[k][j][i]) { the for(k1=0; k1<=tot;k1++)if(fa[k1][j-1][i]&&fa[k][j-1][k1]) theUPD (f[i][j][k],f[i][j-1][k1]+f[k1][j-1][k]);//, printf ("%d-->%d-->%d\n", i,k1,k); the}Elsef[i][j][k]=-inf; the } -InlinevoidRun_merge (intj) { in intI,k;registerintK1; the if(first) { thefirst=0; About for(i=0; i<=tot;i++) for(k=0; k<=tot;k++) g[i][now][k]=f[i][j-1][k]; the return; the } the for(i=0; i<=tot;i++) for(k=0; k<=tot;k++) + for(g[i][now][k]=-inf,k1=0; k1<=tot;k1++)if(fa[k][j-1][k1]) -UPD (g[i][now][k],g[i][pre][k1]+f[k1][j-1][k]); the }Bayi the the - intMain () { -N=read (), scanf ("%i64d",&L); the for(i=1; i<=n;i++) v[i]=read (); the for(i=1; i<=n;i++) scanf ("%s", s+1), Trie (strlen (s+1), V[i]); the Getfail (); the - intA=0; the for(i=0; i<=tot;i++) for(k=0; k<=tot;k++) f[i][0][k]=-inf; the for(i=0; i<=tot;i++) for(j=0;j< -; j + +) fa[next[i][j]][0][i]=1, f[i][0][next[i][j]]=Val[next[i][j]]; the 94 //for (i=0;i<=tot;i++) for (int k1=0;k1<=tot;k1++) if (Fa[i][0][k1]) printf ("%d->%d\n", k1,i); the thenow=1, pre=0; the while(L) {98a++; About if(l&1) Run_merge (a), swap (now,pre); -l>>=1;101 if(! L Break;102 Run_fa (a), Run_f (a);103 }104ll ans=0; the for(i=0; i<=tot;i++) upd (ans,g[0][pre][i]);106printf"%i64d\n", ans);107}
View Code
The game when the problem liver a full 1h ... The last 1min sample: It just went off.
[Codeforces 696D] Legen ...