生活随笔
收集整理的這篇文章主要介紹了
HDU 4787 GRE Words Revenge
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
Description Now Coach Pang is preparing for the Graduate Record Examinations as George did in 2011. At each day, Coach Pang can: "+w": learn a word w "?p": read a paragraph p, and count the number of learnt words. Formally speaking, count the number of substrings of p which is a learnt words. Given the records of N days, help Coach Pang to find the count. For convenience, the characters occured in the words and paragraphs are only '0' and '1'.
Solution 這題網(wǎng)上大部分題解都是錯(cuò)的,只能說數(shù)據(jù)太水 首先這題用到AC自動(dòng)機(jī),如果暴力做每一組詢問需要getfail一次,但是這樣做也能AC. 考慮合并,我們建立兩個(gè)AC自動(dòng)機(jī),保證其中一個(gè)大小\(<\sqrt{n}\) 每一次對(duì)小的進(jìn)行g(shù)etfail,復(fù)雜度只有\(O(\sqrt{n})\) ,如果小的 \(size\) 達(dá)到了 \(\sqrt{n}\) ,考慮暴力合并,復(fù)雜度 \(O(\sqrt{n})\) 注意一個(gè)細(xì)節(jié),一個(gè)單詞只能學(xué)習(xí)一次,所以每加一次需要判斷之前是否存在,網(wǎng)上大部分都沒有做這個(gè)
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <queue>
#include <cmath>
#define RG register
#define il inline
#define iter iterator
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
using namespace std;
const int N=100005,M=600005;
int m,kase=0,ans=0,B=100,root=0;char s[M*10];
queue<int>q;
struct Ac{int size,ch[M][2],fail[M],val[M];int newnode(){size++;ch[size][0]=ch[size][1]=0;fail[size]=0;val[size]=0;return size;}void clear(){size=-1;newnode();}void ins(char *S){int x,len=strlen(s),p=root;for(int i=1;i<len;i++){x=S[i]-'0';if(ch[p][x])p=ch[p][x];else ch[p][x]=newnode(),p=ch[p][x];}val[p]|=1;}void getfail(){while(!q.empty())q.pop();q.push(root);int x,u,v;while(!q.empty()){x=q.front();q.pop();for(int i=0;i<=1;i++){if(!ch[x][i])continue;u=fail[x];while(u && !ch[u][i])u=fail[u];if(ch[u][i] && ch[u][i]!=ch[x][i])fail[ch[x][i]]=ch[u][i];v=ch[x][i];q.push(v);}}}int query(char *S){int x,len=strlen(S),p=root,ret=0,u;for(int i=1;i<len;i++){x=S[i]-'0';while(p && !ch[p][x])p=fail[p];p=ch[p][x];u=p;while(u)ret+=val[u],u=fail[u];}return ret;}bool check(char *S){int len=strlen(S),x,p=root;for(int i=1;i<len;i++){x=S[i]-'0';if(!ch[p][x])return false;p=ch[p][x];}return val[p];}
}A,C;
void dfs(int art,int crt){int x;for(int i=0;i<=1;i++)if(C.ch[crt][i]){if(!A.ch[art][i])A.ch[art][i]=A.newnode();x=A.ch[art][i];A.val[x]|=C.val[C.ch[crt][i]];dfs(x,C.ch[crt][i]);}
}
char b[N];
void Moveit(){int k=ans,len=strlen(s),p=1;k%=(len-1);for(int i=1;i<=k;i++)b[i]=s[i];for(int i=1;k<len-1;i++)s[i]=s[++k];for(int i=len-(ans%(len-1));i<len;i++)s[i]=b[p++];
}
void work()
{printf("Case #%d:\n",++kase);scanf("%d",&m);A.clear();C.clear();ans=0;while(m--){scanf("%s",s);Moveit();if(s[0]=='+'){if(A.check(s) || C.check(s))continue;C.ins(s);if(C.size>B){dfs(0,0);A.getfail();C.clear();}else C.getfail();}else ans=A.query(s)+C.query(s),printf("%d\n",ans);}
}int main()
{int T;cin>>T;while(T--)work();return 0;
}
轉(zhuǎn)載于:https://www.cnblogs.com/Yuzao/p/7661370.html
與50位技術(shù)專家面對(duì)面 20年技術(shù)見證,附贈(zèng)技術(shù)全景圖
總結(jié)
以上是生活随笔 為你收集整理的HDU 4787 GRE Words Revenge 的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔 推薦給好友。