http://www.lydsy.com/JudgeOnline/problem.php?id=1014
学习一发树上Hash。
10s卡时过了。
/* Footprints In The Blood Soaked Snow */ #include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef long long LL; const int maxn = 100005, base = 9875321; int n, num[maxn], P[maxn]; int son[maxn][2], val[maxn], hash[maxn], pre[maxn], size[maxn]; int tot1, root; inline void newnode(int &x, int c, int f) { x = ++tot1; son[x][0] = son[x][1] = 0; val[x] = hash[x] = c; pre[x] = f; size[x] = 1; } inline void pushup(int x) { int l = son[x][0], r = son[x][1]; size[x] = size[l] + 1 + size[r]; hash[x] = (hash[l] + (LL)P[size[l]] * val[x] % base + (LL)P[size[l] + 1] * hash[r] % base) % base; } inline void build(int &x, int l, int r, int f) { if(l > r) return; int mid = l + r >> 1; newnode(x, num[mid], f); build(son[x][0], l, mid - 1, x); build(son[x][1], mid + 1, r, x); pushup(x); } inline void init() { root = tot1 = 0; son[0][0] = son[0][1] = val[0] = hash[0] = pre[0] = size[0] = 0; newnode(root, 0, 0); newnode(son[root][1], 0, root); build(son[son[root][1]][0], 1, n, son[root][1]); pushup(son[root][1]); pushup(root); } inline void rotate(int x) { int y = pre[x], z = pre[y], type = son[y][1] == x; pre[son[y][type] = son[x][!type]] = y; pre[x] = z; if(z) son[z][son[z][1] == y] = x; pre[son[x][!type] = y] = x; pushup(y); pushup(x); } inline void splay(int x, int goal) { while(pre[x] != goal) { int y = pre[x], z = pre[y]; if(z == goal) rotate(x); else if(son[z][1] == y ^ son[y][1] == x) rotate(x), rotate(x); else rotate(y), rotate(x); } if(goal == 0) root = x; } inline int find(int k) { int x = root; while(k != size[son[x][0]] + 1) if(k <= size[son[x][0]]) x = son[x][0]; else k -= size[son[x][0]] + 1, x = son[x][1]; return x; } inline int gethash(int x, int y) { x = find(x); y = find(y + 2); splay(x, 0); splay(y, root); return hash[son[y][0]]; } inline int query(int x, int y) { int l = 1, r = tot1 - y - 1; while(l <= r) { int mid = l + r >> 1; if(gethash(x, x + mid - 1) == gethash(y, y + mid - 1)) l = mid + 1; else r = mid - 1; } return r; } inline void replace(int pos, int c) { int x = find(pos + 1); splay(x, 0); val[x] = c; pushup(x); } inline void insert(int pos, int c) { int x = find(pos + 1), y = find(pos + 2); splay(x, 0); splay(y, root); newnode(son[y][0], c, y); pushup(y); pushup(x); } char str[maxn]; int main() { scanf("%s", str + 1); n = strlen(str + 1); for(int i = 1; i <= n; i++) num[i] = str[i] - 'a' + 1; P[0] = 1; for(int i = 1; i < maxn; i++) P[i] = P[i - 1] * 27, P[i] %= base; init(); int m; scanf("%d", &m); while(m--) { char ch = getchar(); for(; ch != 'Q' && ch != 'R' && ch != 'I'; ch = getchar()); if(ch == 'Q') { int x, y; scanf("%d%d", &x, &y); if(x > y) swap(x, y); printf("%d\n", query(x, y)); } else if(ch == 'R') { int x; scanf("%d%s", &x, str); replace(x, str[0] - 'a' + 1); } else if(ch == 'I') { int x; scanf("%d%s", &x, str); insert(x, str[0] - 'a' + 1); } } return 0; }