版权声明:xgc原创文章,未经允许不得转载。 https://blog.csdn.net/xgc_woker/article/details/82756034
Description
给你一个字符串,每次有加字符和改字符两种操作,让你求从l开始的后缀和从r开始的后缀的最长公共前缀。
Sample Input
madamimadam
7
Q 1 7
Q 4 8
Q 10 11
R 3 a
Q 1 7
I 10 a
Q 2 11
Sample Output
5
1
0
2
1
这题一眼题,
但码代码码了一上午。。。
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef unsigned long long ULL;
const ULL P = 131;
int _min(int x, int y) {return x < y ? x : y;}
int read() {
int s = 0, o = 1; char ch = getchar();
while(ch < '0' || ch > '9') {if(ch == '-') o = -1; ch = getchar();}
while(ch >= '0' && ch <= '9') s = s * 10 + ch - '0', ch = getchar();
return s * o;
}
struct tnode {
int son[2], f, c;
ULL s, sum, lazy;
} t[250010]; int cnt, root;
char ss[110000];
ULL s[110000], o[250010];
int new_node(ULL s, int f) {
int now = ++cnt;
t[now].s = s; t[now].sum = s;
t[now].c = 1; t[now].f = f;
t[now].lazy = 1;
return cnt;
}
void update(int now) {
int lc = t[now].son[0], rc = t[now].son[1];
t[now].c = 1 + t[lc].c + t[rc].c;
t[now].sum = t[now].s * o[t[lc].c] + t[lc].sum + t[rc].sum * o[t[lc].c + 1];
}
void rotate(int x, int fx) {
int f = t[x].f, ff = t[f].f;
int r, R;
r = t[x].son[fx], R = f;
if(r != 0) t[r].f = R;
t[R].son[1 ^ fx] = r;
r = x; R = ff;
t[r].f = R;
if(t[R].son[0] == f) t[R].son[0] = r; else if(t[R].son[1] == f) t[R].son[1] = r;
r = f, R = x;
t[r].f = R;
t[R].son[fx] = r;
update(f);
update(x);
}
void splay(int x, int rt) {
while(t[x].f != rt) {
int f = t[x].f, ff = t[f].f;
if(ff == rt) {
if(t[f].son[0] == x) rotate(x, 1);
else rotate(x, 0);
}
else if(t[f].son[0] == x && t[ff].son[0] == f) rotate(f, 1), rotate(x, 1);
else if(t[f].son[0] == x && t[ff].son[1] == f) rotate(x, 1), rotate(x, 0);
else if(t[f].son[1] == x && t[ff].son[1] == f) rotate(f, 0), rotate(x, 0);
else if(t[f].son[1] == x && t[ff].son[0] == f) rotate(x, 0), rotate(x, 1);
} if(rt == 0) root = x;
}
int findip(int k) {
int x = root;
while(1) {
if(k <= t[t[x].son[0]].c) x = t[x].son[0];
else if(t[t[x].son[0]].c + 1 == k) return x;
else k -= t[t[x].son[0]].c + 1, x = t[x].son[1];
} return x;
}
void add(int x, int c) {
x++; int h1 = findip(x), h2 = findip(x + 1);
splay(h2, 0), splay(h1, h2);
t[h1].son[1] = new_node(c, h1);
update(h1), update(h2);
}
ULL query(int l, int r) {
l++, r++;
int x = findip(l - 1), y = findip(r + 1);
splay(x, 0), splay(y, x);
return t[t[y].son[0]].sum;
}
void change(int x, int c) {
x++; int hh = findip(x);
splay(hh, 0);
t[hh].s = c;
update(hh);
}
int build(int l, int r) {
if(l > r) return 0;
int mid = (l + r) / 2;
int now = mid;
t[now].c = 1;
t[now].s = s[mid];
t[now].lazy = 1;
t[now].son[0] = build(l, mid - 1);
t[now].son[1] = build(mid + 1, r);
if(t[now].son[0]) t[t[now].son[0]].f = now;
if(t[now].son[1]) t[t[now].son[1]].f = now;
update(now); return now;
}
int main() {
scanf("%s", ss + 1);
int n = strlen(ss + 1);
int m = read();
o[0] = 1;
for(int i = 1; i <= n + m; i++) o[i] = o[i - 1] * P;
for(int i = 1; i <= n; i++) s[i + 1] = ss[i];
root = build(1, n + 2); cnt = n + 2; int N = n;
for(int i = 1; i <= m; i++) {
scanf("%s", ss + 1);
if(ss[1] == 'Q') {
int x = read(), y = read();
int l = 1, r = _min(N - x + 1, N - y + 1), ans = 0;
while(l <= r) {
int mid = (l + r) / 2;
if(query(x, x + mid - 1) == query(y, y + mid - 1)) l = mid + 1, ans = mid;
else r = mid - 1;
} printf("%d\n", ans);
} else if(ss[1] == 'R') {
int x = read(); scanf("%s", ss + 1);
change(x, ss[1]);
} else {
int x = read(); scanf("%s", ss + 1);
add(x, ss[1]); N++;
}
}
return 0;
}