题目大意:
如题面所述, 在线状态下接受添加字符和查询某个字符串出现的次数
加上了一些加密的条件使得被迫在线查询
大致思路:
就是后缀自动机的裸题吧=_=
没什么特别的, 直接贴代码好了, 不懂的看代码细节吧
代码如下:
Result : Accepted Memory : 140140 KB Time : 6044 ms
/* * Author: Gatevin * Created Time: 2015/5/5 17:57:21 * File Name: Rin_Tohsaka.cpp */ #include<iostream> #include<sstream> #include<fstream> #include<vector> #include<list> #include<deque> #include<queue> #include<stack> #include<map> #include<set> #include<bitset> #include<algorithm> #include<cstdio> #include<cstdlib> #include<cstring> #include<cctype> #include<cmath> #include<ctime> #include<iomanip> using namespace std; const double eps(1e-8); typedef long long lint; #define foreach(e, x) for(__typeof(x.begin()) e = x.begin(); e != x.end(); ++e) #define SHOW_MEMORY(x) cout<<sizeof(x)/(1024*1024.)<<"MB"<<endl #define maxm 600010 #define maxn 1200010 #define maxl 3000010 struct Suffix_Automation { struct State { State *par; State *go[26]; int right, val; void init(int _val = 0) { val = _val, par = 0, right = 0; memset(go, 0, sizeof(go)); } }; State *root, *last, *cur; State nodePool[maxn]; State* newState(int val = 0) { cur->init(val); return cur++; } void init() { cur = nodePool; root = newState(); last = root; } void extend(int w) { State *p = last; State *np = newState(p->val + 1); np->right = 1; while(p && p->go[w] == 0) { p->go[w] = np; p = p->par; } if(p == 0) { np->par = root; } else { State *q = p->go[w]; if(p->val + 1 == q->val) { np->par = q; } else { State *nq = newState(p->val + 1); memcpy(nq->go, q->go, sizeof(q->go)); nq->right = q->right; nq->par = q->par; q->par = nq; np->par = nq; while(p && p->go[w] == q) { p->go[w] = nq; p = p->par; } } } last = np; } void update() { State *tmp = last; while(tmp != root) { tmp->par->right++; tmp = tmp->par; } } int ask(char *s, int len)//询问这个串出现了几次 { State *now = root; for(int i = 0; i < len; i++) { int w = s[i] - 'A'; if(now->go[w]) now = now->go[w]; else { printf("0\n"); return 0; } } printf("%d\n", now->right); return now->right; } }; char s[maxl]; Suffix_Automation sam; void decode(char *s, int len, int mask) { for(int j = 0; j < len; j++) { mask = (mask*131 + j) % len; swap(s[j], s[mask]); } return; } int main() { int Q; int mask = 0; scanf("%d", &Q); scanf("%s", s); int len = strlen(s); sam.init(); for(int i = 0; i < len; i++) sam.extend(s[i] - 'A'), sam.update(); while(Q--) { scanf("%s", s); switch(s[0]) { case 'Q': scanf("%s", s); len = strlen(s); decode(s, len, mask); mask ^= sam.ask(s, len); break; case 'A': scanf("%s", s); len = strlen(s); decode(s, len, mask); for(int i = 0; i < len; i++) sam.extend(s[i] - 'A'), sam.update(); break; } } return 0; }