P5212 SubString
分析
考虑有动态加字符串的操作,考虑 维护。然后支持一下链上加和单点查询就好了。是挺板子的。
代码
#include<bits/stdc++.h>
using namespace std;
const int N = 1e6 + 400000;
void change(char *s,int ma) {
int len = strlen(s);
for(int j = 0;j < len;j++) {
ma = (ma * 131ll + j) % len;
swap(s[ma],s[j]);
}
for(int j = len;j >= 1;j--) s[j] = s[j - 1];
s[len + 1] = '\0';
}
struct LCT {
int fa[N],ch[N][2],s[N],add[N];
bool nroot(int x) {return ch[fa[x]][0] == x || ch[fa[x]][1] == x;}
void pusha(int x,int val) {add[x] += val;s[x] += val;}
void pushdown(int x) {
if(add[x]) {
if(ch[x][0]) pusha(ch[x][0],add[x]);
if(ch[x][1]) pusha(ch[x][1],add[x]);
add[x] = 0;
}
}
void push(int x) {if(nroot(x)) push(fa[x]);pushdown(x);}
void rot(int x) {
int y = fa[x],z = fa[y],k = ch[y][1] == x,w = ch[x][!k];
if(nroot(y)) ch[z][ch[z][1]==y]=x;ch[x][!k] = y;ch[y][k] = w;
if(w) fa[w] = y;fa[x] = z;fa[y] = x;
}
void splay(int x) {
push(x);while(nroot(x)) {
int y = fa[x],z = fa[y];
if(nroot(y)) rot((ch[y][1]==x)^(ch[z][1]==y)?x:y);
rot(x);
}
}
void access(int x) {for(int y = 0;x;x = fa[y=x]) splay(x),ch[x][1] = y;}
void link(int x,int y) {fa[x] = y;access(y);splay(y);pusha(y,s[x]);}
void cut(int x,int y) {access(x);splay(x);pusha(ch[x][0],-s[x]);fa[ch[x][0]]=0;ch[x][0]=0;}
}t;
struct SAM {
int size,last,len[N],fa[N],nxt[N][26];
void init() {last=size=1;}
void ins(int c) {
int cur = ++size;len[cur]=len[last]+1;
int p = last;t.s[cur]=1;
for(;p&&!nxt[p][c];p=fa[p])nxt[p][c]=cur;
if(!p) fa[cur]=1,t.link(cur,1);
else {
int q=nxt[p][c];
if(len[q]==len[p]+1)fa[cur]=q,t.link(cur,q);
else {
int cl=++size;fa[cl]=fa[q];len[cl]=len[p]+1;
t.link(cl,fa[q]);
for(int i=0;i<26;i++)nxt[cl][i]=nxt[q][i];
for(;p&&nxt[p][c]==q;p=fa[p])nxt[p][c]=cl;
t.cut(q,fa[q]);t.link(cur,cl);t.link(q,cl);
fa[cur]=fa[q]=cl;
}
}
last=cur;
}
int query(char *s) {
int u = 1,len = strlen(s + 1);
for(int i = 1;i <= len;i++) {
int c = s[i] - 'A';
if(!nxt[u][c]) return 0;
else u = nxt[u][c];
}
t.splay(u);return t.s[u];
}
void insert(char *s) {
int len = strlen(s + 1);
for(int i = 1;i <= len;i++) {
int c = s[i] - 'A';ins(c);
}
}
}s;
int main() {
s.init();int mask = 0;
int Q;scanf("%d",&Q);
static char S[N];
scanf("%s",S + 1);
s.insert(S);
while(Q--) {
static char op[100],ch[N];
scanf("%s%s",op,ch);
change(ch,mask);
if(op[0] == 'Q') {
int ans = s.query(ch);
mask ^= ans;
printf("%d\n",ans);
}
else s.insert(ch);
}
}
查看16道真题和解析