The second session of the training game I, after the physical education came back to put this problem, today's training game RANK1, but also the big Brigade abuse, and I also had this problem (although I also had this problem ...) ), the first time in the match handwriting AC automatic machine also with DP, the mood is good.
Gives a collection of strings that contains the number of strings that have a length of more than k characters in the collection.
Obviously in the AC automaton run DP, set DP[U][L][K] indicates the current node u, but also to go L step, the current state is the number of K. At first, the third dimension represents a string containing k, but the problem requires no repetition, so it can only be pressed. Transfer to dp[u][l][k]+=dp[v][l-1][nk],nk for K after U state, that is, directly along the mismatch edge back to go, the can be combined with the added in the line. When CNT (k) >=k is no longer gone, return directly to 26^l.
#include <iostream>#include<cstdio>#include<cstring>#include<cstdlib>#include<algorithm>#include<queue>#defineREP (I,A,B) for (int i=a;i<=b;i++)#defineMS0 (a) memset (A,0,sizeof (a))using namespaceStd;typedefLong Longll;Const intmaxn=252;Const intinf=1e9+Ten;Constll mod=20090717ll;ll Qpow (ll n,ll k,ll p) {ll res=1; while(k) {if(k&1) res= (res* (n%p))%p; N= ((n%p) * (n%p))%p; K>>=1; } returnRes;} ll Cnt (ll K) {ll res=0; for(LL i=0; i<=Ten; i++){ if(k& (1<<i)) res++; } returnRes;}intl,m,k;intdp[252][ -][(1<<Ten)+Ten];structtrie{intch[maxn][ -]; intF[MAXN]; intLAST[MAXN]; intEND[MAXN]; intRt,tot; intNewNode () {++tot; memset (Ch[tot],-1,sizeof(Ch[tot])); End[tot]=0; returntot; } voidinit () {tot=-1; RT=NewNode (); } voidInsertChar*s,intID) {intLen=strlen (s), u=RT; REP (i,0, len-1){ intc=s[i]-'a'; if(ch[u][c]==-1) ch[u][c]=NewNode (); U=Ch[u][c]; } End[u]=(1<<ID); } voidbuild () {Queue<int>Q; F[RT]=rt;last[rt]=RT; REP (c,0, -){ if(~ch[rt][c]) f[ch[rt][c]]=Rt,q.push (Ch[rt][c]); Elsech[rt][c]=RT; } while(!Q.empty ()) { intu=Q.front (); Q.pop (); REP (c,0, -){ if(~ch[u][c]) f[ch[u][c]]=Ch[f[u]][c],q.push (Ch[u][c]); Elsech[u][c]=Ch[f[u]][c]; } if(End[f[u]]) last[u]=F[u]; Elselast[u]=Last[f[u]]; } } int Get(intu) {if(U==RT)return 0; returnend[u]|Get(Last[u]); } intDfsintUintLintk) {int&res=Dp[u][l][k]; if(~res)returnRes; if(Cnt (k) >=k)returnRes=qpow ( -, L,mod); if(l==0)returnres=0; Res=0; intnk=0; REP (c,0, -){ intv=Ch[u][c]; NK=K; if(End[v]) nk|=Get(v); Else if(Last[v]) nk|=Get(Last[v]); Res= (Res+dfs (ch[u][c],l-1, NK))%MOD; } returnRes; }}; Trie AC;CharS[MAXN];intMain () { while(~SCANF ("%d%d%d",&l,&m,&j)) { if(l==0&&m==0&&k==0) Break; //cout<< "l=" <<L<< "m=" <<M<< "k=" <<K<<endl;Ac.init (); REP (i,1, M) {scanf ("%s", s); if(strlen (s) >l)Continue; Ac.insert (S,i-1); } ac.build (); Memset (DP,-1,sizeof(DP)); printf ("%i64d\n", Ac.dfs (Ac.rt,l,0)); } return 0;}
View Code
The first time in the game data structure, a good mood.
But there are some things to summarize:
First or after the submission of the MLE is not only a slight optimization without optimization to no longer optimize, so the mle three times, in fact, there are two times is not necessary, and then there is no consideration of the CNT constant, direct loop to 20, resulting in tle, in fact, directly divided by 2 will be better, the constant is small. Followed by a long long and the choice of int, generally with Longlong the only risk is the MLE, hit the MLE should be considered immediately longlong, or before using Longlong or int.
In summary should be submitted before or before writing the code should be in addition to consider a variety of scenarios to test edge data to prevent WA, but also to consider the time space complexity, to prevent the MLE and tle, when necessary to optimize the constant.
HDU 2825 Wireless Password ac automaton +DP