屯板子屯板子......

HDU2222 - Keywords Search

#include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <list>
#include <set>
#include <utility>
#include <map>
#include <stack>
#include <cctype>
#include <string>
#include <queue>
#define mst(a,b) memset((a),(b),sizeof(a))
#define debug printf("debug\n")
#define INF 0x3f3f3f3f
#define IOS std::ios::sync_with_stdio(false)
const int maxn=1e5+5;
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
struct Trie{
    int next[500005][26];
    int fail[500005];
    int ed[500005];
    int rt,L;
    queue<int> que;
    int newnode(){
        for(int i=0;i<26;i++){
            next[L][i]=-1;
        }
        ed[L]=0;int tmpL=L;L++;
        return tmpL;
    }
    void init(){
        L=0;
        rt=newnode();
        while(!que.empty())    que.pop();
    }
    void insert_(string str){
        int len=str.size();
        int cur=rt;
        for(int i=0;i<len;i++){
            char ch=str[i];
            if(next[cur][ch-'a']==-1){
                next[cur][ch-'a']=newnode();
            }
            cur=next[cur][ch-'a'];
        }
        ed[cur]++;
    } 
    void build(){
        fail[rt]=rt;
        for(int i=0;i<26;i++){
            if(next[rt][i]==-1){
                next[rt][i]=rt;
            }else{
                fail[next[rt][i]]=rt;
                que.push(next[rt][i]);
            }
        }
        while(!que.empty()){
            int u=que.front();
            que.pop();
            for(int i=0;i<26;i++){
                if(next[u][i]==-1){
                    next[u][i]=next[fail[u]][i];
                }else{
                    fail[next[u][i]]=next[fail[u]][i];
                    que.push(next[u][i]);
                }
            }
        }
    }
    int queue(string str){
        int len=str.size();
        int now=rt;
        int ans=0;
        for(int i=0;i<len;i++){
            now=next[now][str[i]-'a'];
            int tmp=now;
            while(tmp!=rt){
                ans+=ed[tmp];
                ed[tmp]=0;
                tmp=fail[tmp];
            }
        }
        return ans;
    }
    void show(){
        for(int i=0;i<100;i++){
            cout<<"i = "<<i<<" "<<ed[i]<<"\n";
        }
    }
};
Trie acmaton;        //内部有大数组,需要开全局变量 
int main()
{
    IOS;
    int t;cin>>t;
    while(t--){
        int n;cin>>n;
        acmaton.init();
        string tmps;
        for(int i=0;i<n;i++){
            cin>>tmps;acmaton.insert_(tmps);
        }
        acmaton.build();
//        acmaton.show();
        cin>>tmps;
        int ans=acmaton.queue(tmps);
        cout<<ans<<"\n";
    }
    return 0;
}

HDU2896 - 病毒侵袭

#include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <list>
#include <set>
#include <utility>
#include <map>
#include <stack>
#include <cctype>
#include <string>
#include <queue>
#define mst(a,b) memset((a),(b),sizeof(a))
#define debug printf("debug\n")
#define INF 0x3f3f3f3f
#define IOS std::ios::sync_with_stdio(false)
const int maxn=1e5+5;
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
vector<int> ansvec;
struct Trie{
    int next[100005][128];
    int fail[100005];
    int edstr[100005];
    int rt,L;
    int scnt;    //字符串数量 
    queue<int> que;
    int newnode(){
        for(int i=0;i<128;i++){
            next[L][i]=-1;
        }
        edstr[L]=0;int tmpL=L;L++;
        return tmpL;
    }
    void init(){
        L=0;scnt=0;
        rt=newnode();
        while(!que.empty())    que.pop();
    }
    void insert_(char str[]){
        int len=strlen(str);
        int cur=rt;
        for(int i=0;i<len;i++){
            char ch=str[i];
            if(next[cur][ch]==-1){
                next[cur][ch]=newnode();
            }
            cur=next[cur][ch];
        }
        edstr[cur]=++scnt;
    } 
    void build(){
        fail[rt]=rt;
        for(int i=0;i<128;i++){
            if(next[rt][i]==-1){
                next[rt][i]=rt;
            }else{
                fail[next[rt][i]]=rt;
                que.push(next[rt][i]);
            }
        }
        while(!que.empty()){
            int u=que.front();
            que.pop();
            for(int i=0;i<128;i++){
                if(next[u][i]==-1){
                    next[u][i]=next[fail[u]][i];
                }else{
                    fail[next[u][i]]=next[fail[u]][i];
                    que.push(next[u][i]);
                }
            }
        }
    }
    void query(char str[]){
        int len=strlen(str);
        int now=rt;
        for(int i=0;i<len;i++){
            now=next[now][str[i]];
            int tmp=now;
            while(tmp!=rt){
                if(edstr[tmp]!=0)
                    ansvec.push_back(edstr[tmp]);
                tmp=fail[tmp];
            }
        }
    }
    void show(){
        for(int i=0;i<100;i++){
            cout<<"i = "<<i<<" edstr[i] = "<<edstr[i]<<"\n";
        }
    }
};
Trie acmaton;        //内部有大数组,需要开全局变量 
char cha[205];
char web[10005];
int main()
{
    int n;
    while(scanf("%d",&n)!=EOF){
        acmaton.init();
        for(int i=0;i<n;i++){
            scanf("%s",cha);acmaton.insert_(cha);
        }
        acmaton.build();
        int m;scanf("%d",&m);
        int webtot=0;
        for(int i=0;i<m;i++){
            ansvec.clear();
            scanf("%s",web);
    //        printf("web: %s\n",web);
            acmaton.query(web);
            int cntt=ansvec.size();
    //        debug;
            if(cntt>0){
                sort(ansvec.begin(),ansvec.end());
                webtot++;
                printf("web %d: ",i+1);
                int sz=ansvec.size();
                for(int i=0;i<sz;i++){
                    if(i==sz-1)    printf("%d\n",ansvec[i]);
                    else printf("%d ",ansvec[i]);
                }
            }
        }
    //    cout<<"total: "<<webtot<<"\n";//
        printf("total: %d\n",webtot);
    }
    return 0;
}