发现插入操作很少,可以每次插入完以后暴力重算hash值。查询的时候二分判断就可以了。
/* I will wait for you*/
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <ctime>
#include <algorithm>
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
#include <deque>
#include <map>
#include <set>
#include <string>
#define make make_pair
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
const int maxn = 200010;
const int maxm = 1010;
const int maxs = 26;
const int inf = 0x3f3f3f3f;
const int P = 1000000007;
const double error = 1e-9;
inline int read()
{
int x = 0, f = 1; char ch = getchar();
while (ch <= 47 || ch >= 58)
f = (ch == 45 ? -1 : 1), ch = getchar();
while (ch >= 48 && ch <= 57)
x = x * 10 + ch - 48, ch = getchar();
return x * f;
}
ll hash[maxn], id[maxn], fac[maxn] = {1};
char s[maxn], t[maxn], type[maxn], ins[maxn];
void make_hash()
{
int n = strlen(s + 1);
for (int i = 1; i <= n; i++)
hash[i] = (hash[i - 1] * 131 + s[i]) % P;
}
void insert(int pos, char a)
{
int n = strlen(s + 1);
for (int i = n + 1; i > pos; i--)
s[i] = s[i - 1];
int m = strlen(t + 1);
for (int i = 1; i <= m; i++)
if (id[i] >= pos) id[i]++;
s[min(pos, n + 1)] = a;
}
ll query_hash(int l, int r)
{
ll hash_tmp = hash[l - 1] * fac[r - l + 1] % P;
return (hash[r] - hash_tmp + P) % P;
}
int solve(int u, int v)
{
int n = strlen(s + 1);
int l = 0, r = min(n - u + 1, n - v + 1);
while (l != r) {
int mid = (l + r + 1) / 2;
ll tmp_u = query_hash(u, u + mid - 1);
ll tmp_v = query_hash(v, v + mid - 1);
if (tmp_u == tmp_v) l = mid;
if (tmp_u != tmp_v) r = mid - 1;
}
return (l + r) / 2;
}
int main()
{
int q, m; scanf("%s%d", s + 1, &q);
memcpy(t, s, sizeof s);
make_hash(), m = strlen(s + 1);
for (int i = 1; i <= m; i++) id[i] = i;
for (int i = 1; i <= 100000; i++)
fac[i] = (ll) fac[i - 1] * 131 % P;
for (int i = 1, u, v, pos; i <= q; i++) {
scanf("%s", type);
if (type[0] == 'I') {
scanf("%s%d", ins, &pos);
insert(pos, ins[0]), make_hash();
}
if (type[0] == 'Q') {
scanf("%d%d", &u, &v);
printf("%d\n", solve(id[u], id[v]));
}
}
return 0;
}