https://vjudge.net/problem/UVA-12538
模拟一个版本控制编辑器,有以下操作:
在线询问某个版本的具体情况, 显然是要可持久化的,可以用非旋转treap实现,这里先用rope实现。。。过两天填可持久化平衡树的坑。。。
#include
#include
using namespace std;
using namespace __gnu_cxx;
const int N = 50000 + 10;
char str[N];
crope rs, his[N];
int main()
{
int n, opt, v, p, len;
int num = 0, cur = 0;
scanf("%d", &n);
while(n--)
{
scanf("%d", &opt);
if(opt == 1)
{
scanf("%d%s", &p, str);
p -= num;
rs.insert(p, str);
his[++cur] = rs;
}
else if(opt == 2)
{
scanf("%d%d", &p, &len);
p -= num, len -= num;
rs.erase(p-1, len);
his[++cur] = rs;
}
else if(opt == 3)
{
scanf("%d%d%d", &v, &p, &len);
v -= num, p -= num, len -= num;
string s = his[v].substr(p-1, len).c_str();
num += count(s.begin(), s.end(), 'c');
printf("%s\n", s.c_str());
// crope tp = his[v].substr(p-1, len);
// num += count(tp.begin(), tp.end(), 'c');
// cout << tp << endl;
// printf("%s\n", tp.c_str());
}
}
return 0;
}
//2017.9.27
//可持久化treap类似于可持久化线段树,原本的形态保持不变,通过新增节点的方式进行merge和split操作,很机智。。。
#include
using namespace std;
typedef pair<int, int> proot;
const int N = 4000000 + 10, M = 50000 + 10, INF = 0x3f3f3f3f;
struct node
{
int l, r, val, pri, sz;
void init(int _val, int _pri, int _sz)
{
val = _val, pri = _pri, sz = _sz;
l = r = 0;
}
}tr[N];
char s[M];
int root[M];
int tot, num;
void init()
{
tot = 0;
tr[0].init(0, 0, 0);
}
int new_node(int val)
{
tr[++tot].init(val, rand(), 1);
return tot;
}
void update(int x)
{
tr[x].sz = 1 + tr[tr[x].l].sz + tr[tr[x].r].sz;
}
int Copy(int x)
{
tr[++tot] = tr[x];
return tot;
}
int Merge(int x, int y)
{
if(!x || !y) return x + y;
int z;
if(tr[x].pri < tr[y].pri)
{
z = Copy(x);
tr[z].r = Merge(tr[z].r, y);
}
else
{
z = Copy(y);
tr[z].l = Merge(x, tr[z].l);
}
update(z);
return z;
}
proot split(int x, int k)
{
//if(!k) return proot(0, x);
if(!x) return proot(0, 0);
proot y;
if(k <= tr[tr[x].l].sz)
{
int z = Copy(x);
y = split(tr[x].l, k);
tr[z].l = y.second;
y.second = z;
update(z);
}
else
{
int z = Copy(x);
y = split(tr[x].r, k - tr[tr[x].l].sz - 1);
tr[z].r = y.first;
y.first = z;
update(z);
}
return y;
}
void build(int &x, int l, int r)
{
if(l > r) return;
int mid = (l + r) >> 1;
x = new_node(s[mid]);
build(tr[x].l, l, mid-1);
build(tr[x].r, mid+1, r);
update(x);
}
void Insert(int &x, int last, int pos)
{
int len = strlen(s + 1);
proot y = split(last, pos);
build(x, 1, len);
x = Merge(Merge(y.first, x), y.second);
}
void del(int &x, int last, int pos, int len)
{
proot t1 = split(last, pos-1);
proot t2 = split(t1.second, len);
x = Merge(t1.first, t2.second);
}
void print(int x)
{
if(!x) return;
print(tr[x].l);
printf("%c", (char)tr[x].val);
if(tr[x].val == 'c') ++num;
print(tr[x].r);
}
void print(int x, int pos, int len)
{
proot t1 = split(x, pos-1);
proot t2 = split(t1.second, len);
print(t2.first);
printf("\n");
}
int main()
{
srand((unsigned)time(NULL));
int n, opt, v, p, len, cur = 0;
init();
num = 0;
scanf("%d", &n);
while(n--)
{
scanf("%d", &opt);
if(opt == 1)
{
scanf("%d%s", &p, s+1);
p -= num;
Insert(root[cur+1], root[cur], p);
++cur;
}
else if(opt == 2)
{
scanf("%d%d", &p, &len);
p -= num, len -= num;
del(root[cur+1], root[cur], p, len);
++cur;
}
else if(opt == 3)
{
scanf("%d%d%d", &v, &p, &len);
v -= num, p -= num, len -= num;
print(root[v], p, len);
}
}
return 0;
}