splay的区间操作(区间表示),Hash离散,二分答案
Hash值(代码中是RK的hash函数)是一个节点域,除此就没什么特别的了
#include<bits/stdc++.h>
using namespace std;
inline int get_int() {
char c; int res = 0;
while(!isdigit(c = getchar()));
for(res = c - '0'; isdigit(c = getchar()); )
res = res * 10 + c - '0';
return res;
}
inline char get_ch() {
char c;
while(!isalpha(c = getchar()));
return c;
}
typedef unsigned int uint;
const int MAXN = 100000;
const uint seed = 131;
uint Pow[MAXN + 10];
struct node {
int key, size; uint RK;
node *c[2];
node():key(0), size(0), RK(0) { c[0] = c[1] = this; }
node(uint key, node *_c0, node *_c1):key(key) { c[0] = _c0; c[1] = _c1; }
node *rz() { return RK = (c[0]->RK * seed + (uint)key) * Pow[c[1]->size] + c[1]->RK, size = c[0]->size + c[1]->size + 1, this; }
} Tnull, *null = &Tnull;
struct splay {
node *root;
void zig(bool d) {
node *t = root->c[d];
root->c[d] = null->c[d];
null->c[d] = root;
root = t;
}
void zigzig(bool d) {
node *t = root->c[d]->c[d];
root->c[d]->c[d] = null->c[d];
null->c[d] = root->c[d];
root->c[d] = null->c[d]->c[!d];
null->c[d]->c[!d] = root->rz();
root = t;
}
void finish(bool d) {
node *t = null->c[d], *p = root->c[!d];
while(t != null) {
t = null->c[d]->c[d];
null->c[d]->c[d] = p;
p = null->c[d]->rz();
null->c[d] = t;
}
root->c[!d] = p;
}
void select(int k) {
int t;
while(1) {
bool d = k > (t = root->c[0]->size);
if(k == t || root->c[d] == null) break;
if(d) k -= t + 1;
bool dd = k > (t = root->c[d]->c[0]->size);
if(k == t || root->c[d]->c[dd] == null) { zig(d); break; }
if(dd) k -= t + 1;
d != dd ? zig(d), zig(dd) : zigzig(d);
}
finish(0), finish(1);
root->rz();
}
void modify(int k, int x) {
select(k - 1);
root->key = x;
root->rz();
}
void ins(int k, int x) {
select(k - 1);
node* oldroot = root;
root = new node(x, oldroot->c[0], oldroot);
oldroot->c[0] = null;
oldroot->rz();
root->rz();
}
node *split(int st, int len) {
select(st - 2);
node *oldroot = root;
root = oldroot->c[1];
select(len);
oldroot->c[1] = root->rz();
swap(root, oldroot);
return oldroot->c[0];
}
} sp;
int ops;
char buf[MAXN + 10];
node *Build(int l, int r) {
if(l > r) return null;
int mid = l + (r - l) / 2;
return (new node(buf[mid], Build(l, mid - 1), Build(mid + 1, r)))->rz();
}
int query(int st1, int st2) {
int L = 0, R = sp.root->size - max(st1, st2);
while(L < R) {
int M = L + (R - L + 1) / 2;
uint a = sp.split(st1, M)->RK;
uint b = sp.split(st2, M)->RK;
if(a == b) L = M;
else R = M - 1;
}
return L;
}
int main() {
Pow[0] = 1;
for(int i = 1; i <= MAXN; i++) Pow[i] = Pow[i - 1] * seed;
int len;
scanf("%s%d", buf + 1, &ops);
len = strlen(buf + 1);
buf[0] = buf[len + 1] = '&';
buf[len + 2] = 0;
sp.root = Build(0, len + 1);
for(int i = 1; i <= ops; i++) {
char opt; int x, y; char c;
opt = get_ch();
if(opt == 'Q') {
x = get_int(); y = get_int();
printf("%d\n", query(x + 1, y + 1));
}
else if(opt == 'R') {
x = get_int(); c = get_ch();
sp.modify(x + 1, c);
}
else {
x = get_int(); c = get_ch();
sp.ins(x + 2, c);
}
}
return 0;
}