用平衡树瞎维护一下哈希串即可。
不知道为啥这题写Treap这么慢= =
P.S.提取出区间之后一定要判断是否为空区间!插入的时候计数器也要++!
#include <bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for (int i = a , _ = b ; i <= _ ; i ++)
#define per(i,a,b) for (int i = a , _ = b ; i >= _ ; i --)
#define pii pair<char , ull>
#define fir first
#define sec second
const int maxn = 100007;
const int magic1 = 13;
const int magic2 = 17;
inline int rd() {
char c = getchar();
while (!isdigit(c)) c = getchar() ; int x = c - '0';
while (isdigit(c = getchar())) x = x * 10 + c - '0';
return x;
}
#define gprintf(...) //fprintf(stderr , __VA_ARGS__)
inline char rd_ch() {
char c = getchar();
while (!isalpha(c)) c = getchar();
return c;
}
typedef unsigned int ull;
inline int rnd() {
static int rand_seed = 42071823;
rand_seed += rand_seed << 1 | 1;
return rand_seed;
}
ull Pow[maxn];
pii H[maxn];
int n;
char str[maxn];
namespace Treap {
struct node {
node *l , *r;
int sz , pri;
ull sum,tag;
pii val;
node () { }
node (pii _key): val(_key) , pri(rnd())
{ l = r = NULL , sum = (ull) _key.fir * _key.sec , tag = 0 , sz = 1; }
inline void upd() {
sz = 1 , sum = (ull) val.fir * val.sec;
if (l) sz += l->sz , sum += l->sum;
if (r) sz += r->sz , sum += r->sum;
}
inline void Tag(int v) {
sum *= Pow[v] , val.sec *= Pow[v];
tag += v;
}
inline void push() {
if (!tag) return;
if (l) l->Tag(tag);
if (r) r->Tag(tag);
tag = 0;
}
}mem_pool[maxn] , *rt;
int mem_top;
typedef pair<node* , node*> data;
inline node *newnode(pii x) {
node *u = &mem_pool[mem_top ++];
*u = node(x);
return u;
}
inline int Size(node *u) {
return u ? u->sz : 0;
}
inline ull Sum(node *u) {
return u ? u->sum : 0;
}
node *join(node *u , node *v) {
if (!u) return v;
if (!v) return u;
if (u->pri < v->pri) {
u->push();
u->r = join(u->r , v);
u->upd();
return u;
} else {
v->push();
v->l = join(u , v->l);
v->upd();
return v;
}
}
data split(node *u , int k) {
if (!u) return data(NULL , NULL);
data t;
u->push();
if (Size(u->l) >= k) {
t = split(u->l , k);
u->l = t.sec , t.sec = u;
} else {
t = split(u->r , k - Size(u->l) - 1);
u->r = t.fir , t.fir = u;
}
u->upd();
return t;
}
pii get_kth(int k) {
node *u = rt;
for (;;) {
int t = Size(u->l) + 1;
if (t == k)
return u->val;
else if (t < k)
k -= t , u = u->r;
else
u = u->l;
}
}
ull get_sum(int l , int r) {
data t1 = split(rt , r) , t2 = split(t1.fir , l - 1);
ull ret = Sum(t2.sec);
rt = join(join(t2.fir , t2.sec) , t1.sec);
return ret;
}
void insert(int p , pii x) {
data t1 = split(rt , p);
if (t1.sec)
t1.sec->Tag(1);
rt = join(t1.fir , join(newnode(x) , t1.sec));
}
void set_val(int p , pii x) {
data t1 = split(rt , p) , t2 = split(t1.fir , p - 1);
t2.sec->val = x;
t2.sec->upd();
rt = join(join(t2.fir , t2.sec) , t1.sec);
}
void build(pii *a , int n) {
static node *stack[maxn] , *u , *pre;
stack[1] = NULL;
int top = 0;
rep (i , 1 , n) {
u = newnode(a[i]);
pre = NULL;
while (top && stack[top]->pri > u->pri) {
stack[top] -> upd();
pre = stack[top --];
}
u->l = pre;
if (top) stack[top]->r = u;
stack[++ top] = u;
}
while (top) stack[top --]->upd();
rt = stack[1];
}
}
inline void init() {
Pow[0] = 1;
rep (i , 1 , maxn - 1) Pow[i] = Pow[i - 1] * magic1;
}
void input() {
scanf("%s" , str + 1);
n = strlen(str + 1);
rep (i , 1 , n) H[i] = pii(str[i] , Pow[i - 1]);
Treap::build(H , n);
}
inline bool same(int l1 , int r1 , int l2 , int r2 , int L) {
if (Treap::get_sum(l1 , r1) * Pow[L] != Treap::get_sum(l2 , r2))
return 0;
return 1;
}
void query(int x) {
using namespace Treap;
int y = rd();
if (x > y) swap(x , y);
int l = 1 , r = n - y + 1 , L = y - x , ans = 0;
while (l <= r) {
int m = (l + r) >> 1;
if (same(x , x + m - 1 , y , y + m - 1 , L))
l = m + 1 , ans = m;
else
r = m - 1;
}
printf("%d\n" , ans);
}
void modif(int p) {
using namespace Treap;
char c = rd_ch();
set_val(p , pii(c , Pow[p - 1]));
}
void inser(int p) {
using namespace Treap;
char c = rd_ch();
++ n;
insert(p , pii(c , Pow[p]));
}
void solve() {
int m = rd();
rep (i , 1 , m) {
char cmd = rd_ch();
int x = rd();
switch (cmd) {
case 'Q' : query(x); break;
case 'R' : modif(x); break;
case 'I' : inser(x); break;
}
}
}
int main() {
init();
#ifndef ONLINE_JUDGE
freopen("prefix1.in" , "r" , stdin);
freopen("info.txt" , "w" , stderr);
#endif
input();
solve();
return 0;
}