http://acm.hust.edu.cn/vjudge/contest/view.action?cid=21239#overview
木板题,统计包含个数
#include <iostream> #include <stdio.h> #include <string.h> #include <vector> #include <queue> using namespace std; const int CHAR = 26; const int TOTLEN = 5e5 + 9; const int MAXLEN = 1e6 + 9; struct Node{ Node *fail , *next[CHAR]; int val; void init(){ fail = NULL; val = 0; memset(next , 0 , sizeof(next)); } }; class ACM{ public: void init(); void insert(char * str); void build(); int find(char * str); private: Node * newnode(); Node acm[TOTLEN]; Node * root; int size; }; Node * ACM::newnode(){ acm[size].init(); return &acm[size++]; } void ACM::init(){ size = 0; root = newnode(); } void ACM::insert(char * str){ Node * p = root; for ( ; *str ; ++str){ int ch = *str - 'a'; if (p -> next[ch] == NULL) p -> next[ch] = newnode(); p = p -> next[ch]; } p -> val ++; } void ACM::build(){ static queue<Node *> q; q.push(root); while(!q.empty()){ Node * tmp = q.front() ; q.pop(); Node * p; for (int i = 0 ; i < CHAR ; ++i){ Node *& now = tmp -> next[i]; if (now != NULL){ q.push(now); if (tmp == root){ now -> fail = root; continue; } p = tmp -> fail; while(p != NULL){ if (p -> next[i] != NULL){ now -> fail = p -> next[i]; break; } p = p -> fail; } if (p == NULL) now -> fail = root; } else{ if (tmp == root) now = root; else now = tmp -> fail -> next[i]; } } } } int ACM::find(char * str){ Node *p = root; int ans = 0; for ( ; *str ; ++str){ int ch = *str - 'a'; p = p -> next[ch]; if (p == NULL) p = root; Node * tmp = p; while(tmp != root && tmp ->val != -1){ ans += tmp -> val; tmp -> val = -1; tmp = tmp -> fail; } } return ans; } ACM ac; char str[MAXLEN]; void solve(){ int n; scanf("%d" , &n); ac.init(); while(n--){ scanf("%s" , str); ac.insert(str); } ac.build(); scanf("%s" , str); printf("%d\n" , ac.find(str)); } int main(){ // freopen("0" ,"r" ,stdin); int _ = 0; scanf("%d" , &_); while(_--) solve(); }
建立自动机,搞出转移矩阵,快速幂。。
% 比 - 慢多了啊!!
#include <functional> #include <algorithm> #include <iostream> #include <fstream> #include <sstream> #include <iomanip> #include <numeric> #include <cstring> #include <cassert> #include <cstdio> #include <string> #include <vector> #include <bitset> #include <queue> #include <stack> #include <cmath> #include <ctime> #include <list> #include <set> #include <map> using namespace std; #define Rush for(int ____T , scanf("%d" , &____T); ____T--;) #define DO(n) for ( int ____n ## __line__ = n; ____n ## __line__ -- ; ) #define ALL(A) A.begin(), A.end() #define BSC(A, x) (lower_bound(ALL(A), x) - A.begin()) #define CTN(T, x) (T.find(x) != T.end()) #define SZ(A) int(A.size()) #define PB push_back #define MP(A, B) make_pair(A, B) #define fi first #define se second typedef long long LL; typedef vector<int> VI; typedef map<int, int> MII; typedef pair<int, int> PII; typedef pair<LL, LL> PLL; template<class T> inline void RST(T &A){memset(A, 0, sizeof(A));} template<class T> inline void FLC(T &A, int x){memset(A, x, sizeof(A));} template<class T> inline void CLR(T &A){A.clear();} //} /** Constant List .. **/ //{ const int dx4[] = {-1, 0, 1, 0}; const int dy4[] = {0, 1, 0, -1}; const int dx8[] = {-1, 0, 1, 0 , -1 , -1 , 1 , 1}; const int dy8[] = {0, 1, 0, -1 , -1 , 1 , -1 , 1}; const int dxhorse[] = {-2 , -2 , -1 , -1 , 1 , 1 , 2 , 2}; const int dyhorse[] = {1 , -1 , 2 , -2 , 2 ,-2 , 1 ,-1}; const int MOD = 1000000007; //int MOD = 99990001; const int INF = 0x3f3f3f3f; const LL INFF = 1LL << 60; const double EPS = 1e-9; const double OO = 1e15; const double PI = acos(-1.0); //M_PI; #pragma comment(linker, "/STACK:36777216") //} template<class T> inline void checkMin(T &a,const T b){if (b<a) a=b;} template<class T> inline void checkMax(T &a,const T b){if (a<b) a=b;} //} template<class T> inline T low_bit(T x) {return x & -x;} /*****************************************************************/ const int CHAR = 4; const int TOT = 129; int next[TOT][CHAR] , fail[TOT]; bool virus[TOT]; int id[128]; const int Dic[] = {'A' , 'C' , 'G' ,'T'}; int L , root; int newNode(){ for (int i = 0 ; i < CHAR; ++i) next[L][i] = -1; virus[L] = 0; fail[L] = 0; return L++; } void init(){ L = 0; root = newNode(); } void insert(char *s){ int now = root; for (int i = 0 ; s[i] ; ++i){ int ch = id[s[i]]; if (next[now][ch] == -1) next[now][ch] = newNode(); now = next[now][ch]; } virus[now] = 1; } void build(){ queue<int> Q; for (int i = 0 ; i < CHAR ; ++i) if (next[root][i] == -1) next[root][i] = root; else{ fail[next[root][i]] = root; Q.push(next[root][i]); } while(!Q.empty()){ int now = Q.front(); virus[now] |= virus[fail[now]]; Q.pop(); for (int i = 0 ; i < CHAR ; ++i) if (next[now][i] == -1) next[now][i] = next[fail[now]][i]; else{ fail[next[now][i]] = next[fail[now]][i]; Q.push(next[now][i]); } } } const int MATN = 129; const int modo = 1e5; struct Mat{ int Matn , Matm; int a[MATN][MATN]; Mat(){ Matn = 0; Matm = 0; memset(a , 0 , sizeof(a)); } void output(){ cout << "OUTPUT" << endl; for (int i = 0 ; i < Matn ; ++i){ for (int j = 0 ; j < Matm ; ++j){ printf("%d ",a[i][j]); } printf("\n"); } } void init(){ Matn = 0;Matm = 0; memset(a , 0 , sizeof(a)); } Mat operator + (const Mat & A) const{ Mat ret = A; for (int i = 0 ; i < Matn ; ++i){ for (int j = 0 ; j < Matm ; ++j) ret.a[i][j] = (ret.a[i][j] + a[i][j]) % modo; } return ret; } Mat operator * (const Mat & A) const{ Mat c ; c.Matn = Matn; c.Matm = A.Matm; for (int i = 0 ; i < Matn ; ++i) for (int j = 0 ; j < A.Matm ; ++j) for (int k = 0 ; k < Matm ; ++k){ c.a[i][j] = (c.a[i][j] + ((long long)a[i][k] * A.a[k][j])%modo); if (c.a[i][j] >= modo) c.a[i][j] -= modo; } return c; } void initI(){ memset(a, 0 , sizeof(a)); for (int i = 0 ; i < Matn ; ++i) a[i][i] = 1; } Mat power(int k){ Mat c = *this , b; b.init(); b.Matn = Matn ; b.Matm = Matm; b.initI(); while(k){ if (k & 1) b = b * c; c = c * c; k >>= 1; } return b; } }P , Q; char A[15]; int n , m; void solve(){ init(); DO(m){ scanf("%s" , A); insert(A); } build(); P.init(); P.Matn = P.Matm = L; for (int i = 0 ; i < L ; ++i){ if (virus[i]) continue; for (int j = 0 ; j < 4 ; ++j){ int ni = next[i][j]; if (ni == -1) ni = root; // assert(ni != -1); if (virus[ni]) continue; P.a[i][ni]++; } } // P.output(); P = P.power(n); // P.output(); Q.init(); Q.Matn = 1 , Q.Matm = L; Q.a[0][0] = 1; // for(int i = 0 ; i < L ; ++i) Q.a[0][i] = 1; Q = Q * P; // Q.output(); int ans = 0; for (int i = 0 ; i < L ; ++i) if (!virus[i]){ ans = (ans + Q.a[0][i]); if (ans >= modo) ans -= modo; } printf("%d\n" , ans); } int main(){ id['A'] = 0; id['C'] = 1; id['G'] = 2; id['T'] = 3; while(~scanf("%d%d" , &m , &n))solve(); }
http://acm.hdu.edu.cn/showproblem.php?pid=3068
http://poj.org/problem?id=3974
http://acmpj.zstu.edu.cn/JudgeOnline/showproblem?problem_id=3780
http://acmpj.zstu.edu.cn/JudgeOnline/showproblem?problem_id=3769木板
#include <iostream> #include <stdio.h> #include <string.h> using namespace std; const int N = 120000; namespace Manacher_String{ char Ma[N << 1]; int rad[N << 1] , ml; void Manacher(char *s , int len){ int l = 0; Ma[ l ++ ] = '.'; Ma[ l ++ ] = ','; for (int i = 0 ; i < len ; ++i){ Ma[ l ++ ] = s[i]; Ma[ l ++ ] = ','; } Ma[l] = 0; int pnow = 0 , pid = 0; for (int i = 1 ; i < l ; ++i){ if (pnow > i) rad[i] = min(rad[(pid << 1) - i] , pnow - i); else rad[i] = 1; for ( ; Ma[i - rad[i]] == Ma[i + rad[i]] ; rad[i] ++); if (i + rad[i] > pnow){ pnow = i + rad[i]; pid = i; } } ml = l; } }using namespace Manacher_String; char s[N]; int main(){ while(~scanf("%s" , s)){ int n = strlen(s); Manacher(s , n); int ans = 0; for (int i = 1 ; i < ml ; ++i){ ans = max(ans , rad[i] - 1); } printf("%d\n" , ans); } }
http://acm.hdu.edu.cn/showproblem.php?pid=3948
hash 一下即可