您的位置:首页 > 其它

UVA 12538 Version Controlled IDE(可持久化treap)

2015-05-29 11:50 375 查看
题意:给定一个字符串,要求支持3种操作:

1:版本+1,当前版本某个位置插入一个字符串;

2:版本+1,删除当前版本某段字符串;

3:询问以前版本的某段字符串。

强制在线。

思路:可持久化treap。。。

贴下模板。。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

#define N 7000020

int ch
[2], rd
, val
, s
;
int tot;

int copy(int i) {
	int k = ++tot;

	ch[k][0] = ch[i][0];
	ch[k][1] = ch[i][1];
	rd[k] = rd[i];
	val[k] = val[i];
	s[k] = 1;
	return k;
}
void push_up(int x) {
	s[x] = s[ch[x][0]] + s[ch[x][1]] + 1;
}
int merge(int x, int y) {
	if(x == 0) return y;
	if(y == 0) return x;
	if(rd[x] < rd[y]) {
		int k = copy(x);
		ch[k][1] = merge(ch[x][1], y);
		push_up(k);
		return k;
	}
	else {
		int k = copy(y);
		ch[k][0] = merge(x, ch[y][0]);
		push_up(k);
		return k;
	}
}

void split(int x, int k, int &L, int &R) {
	if(s[x] <= k) {
		L = x, R = 0;
		return;
	}
	int tmp = s[ch[x][0]];
	int t = copy(x);
	int a, b;
	if(k <= tmp) {
		split(ch[x][0], k, a, b);
		ch[t][0] = b;
		R = t;
		L = a;
	}
	else {
		split(ch[x][1], k - tmp - 1, a, b);
		ch[t][1] = a;
		L = t;
		R = b;
	}
	push_up(t);
}

int q, ccnt;
int now, root[50020];
char str[120];
int build(int l, int r, int pre) {
	if(l > r) return 0;
	int m = (l + r) / 2;
	int x = ++tot;
	rd[x] = rand() + pre;
	s[x] = 1;
	val[x] = str[m];
	ch[x][0] = build(l, m - 1, rd[x]);
	ch[x][1] = build(m + 1, r, rd[x]);
	push_up(x);
	return x;
}

void out(int x) {
	if(x == 0) return;
	out(ch[x][0]);
	putchar(val[x]);
	if(val[x] == 'c') ++ccnt;
	out(ch[x][1]);
}

int main() {
	//freopen("tt.txt", "r", stdin);
	while(scanf("%d", &q) != EOF) {
		ccnt = 0;
		tot = 0;
		now = 0;
		memset(root, 0, sizeof root);
		while(q--) {
			int op;
			scanf("%d", &op);
			if(op == 1) {
				int p;
				scanf("%d%s", &p, str + 1);
				int t = build(1, strlen(str + 1), 0);
				p -= ccnt;
				++now;
				if(p == 0) {
					root[now] = merge(t, root[now-1]);
				}
				else if(p == s[root[now-1]])
					root[now] = merge(root[now-1], t);
				else {
					int L, R;
					split(root[now-1], p, L, R);
					root[now] = merge(L, t);
					root[now] = merge(root[now], R);
				}
			}
			else if(op == 2) {
				++now;
				int p, c;
				scanf("%d%d", &p, &c);
				p -= ccnt, c -= ccnt;
				int L, R, X, Y;
				split(root[now-1], p - 1, L, R);
				split(R, c, X, Y);
				root[now] = merge(L, Y);
			}
			else {
				int v, p, c;
				scanf("%d%d%d", &v, &p, &c);
				v -= ccnt, p -= ccnt, c -= ccnt;
				int L, R, X, Y;
				split(root[v], p - 1, L, R);
				split(R, c, X, Y);
				out(X);
				puts("");
			}
		}
	}
	return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: