UVA 12538 Version Controlled IDE 可持久化treap

Time Limit:  3000MSMemory Limit:  Unknown64bit IO Format:  %lld & %llu

12538 Version Controlled IDE 
Programmers use version control systems to manage les in their projects, but in these systems, versions 
are saved only when you manually submit. Can you implement an IDE that automatically saves a new 
version whenever you insert or delete a string? 
Positions in the bu er are numbered from 1 from left to right. Initially, the bu er is empty and in 
version 0. Then you can execute 3 commands (vnow means the version before executing the command, 
and L[v] means the length of bu er at version v): 
1 p s: insert string s after position p (0 p L[vnow], p = 0 means insert before the start of the 
bu er). s contains at most 1 and at most 100 letters. 
2 p c: remove c characters starting at position p (p 1; p + c L[vnow] + 1). The remaining 
charactesr (if any) will be shifted left, lling the blank 
3 v p c: print c characters starting at position p (p 1; p + c L[v] + 1), in version v (1 v 
vnow). 
The rst command is guaranteed to be command 1(insert). After executing each command 1 or 2, 
version is incremented by 1. 
Input 
There is only one test case. It begins with a single integer n (1 n 50; 000), the number of commands. 
Each of the following n lines contains a command. The total length of all inserted string will not 
exceed 1,000,000. 
Output 
Print the results of command 3, in order. The total length of all printed strings will not exceed 200,000. 
Obfuscation: 
In order to prevent you from preprocessing the command, we adopt the following obfuscation scheme: 
Each type-1 command becomes 1 p + d s 
Each type-2 command becomes 2 p + d c + d 
Each type-3 command becomes 3 v + d p + d c + d 
Where d is the number of lowercase letter `c' you printed, before processing this command. 
Before the obfuscation, the sample input would be: 

1 0 abcdefgh 
2 4 3 
3 1 2 5 
3 2 2 3 
1 2 xy 
3 3 2 4 
This is the real input that your program must process when it reads the Sample Input 
below.Universidad de Valladolid OJ: 12538 { Version Controlled IDE 2/2 
Sample Input 

1 0 abcdefgh 
2 4 3 
3 1 2 5 
3 3 3 4 
1 4 xy 
3 5 4 6 
Sample Output 
bcdef 
bcg 
bxyc 






维护一个文本,p位置插入串,p位置删除长度c的串,
查询历史版本某个位置开始的串。强制在线
神一样的可持久化treap

不用rotate操作
merge(a,b):把 treap<a>与treap<b >合并成treap<c>
split(a,k):把treap<a >的前k个变成一个treap<b>,剩下的元素变成treap<c>

另外可用STL  ext/rope  块状链表 详见:  http://www.sgi.com/tech/stl/Rope.html

研究中,代码是悄悄拿来参考哒


#include<cstdio>
#include<ctime>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=1111111;
int dif,m,th;
char key[maxn*10];
int root[55555]={0};
char s[maxn];
int son[maxn*20][2]={0};
int size[maxn*20]={0};
int val[maxn*20]={0};
int stuck[maxn]={0};
int top=0;
inline void update(int x)
{
    if (size[son[x][0]]==0)son[x][0]=0;
    if (size[son[x][1]]==0)son[x][1]=0;
    size[x]=size[son[x][0]]+size[son[x][1]]+1;
}
inline int build()
{
    top=0;
    int n=strlen(s+1);
    for (int i=1;i<=n;i++)
    {
        key[++th]=s[i];
        val[th]=rand();
        stuck[top+1]=0;
        while (top>=1 && val[stuck[top]]<val[th])update(stuck[top--]);
        son[th][0]=stuck[top+1];
        if (top)son[stuck[top]][1]=th;
        stuck[++top]=th;
    }
    while (top)update(stuck[top--]);
    return stuck[1];
}

inline void copy(int x, int y)
{
    key[y]=key[x];
    son[y][0]=son[x][0];
    val[y]=val[x];
    son[y][1]=son[x][1];
    size[y]=size[x];
}
void breakup(int x,int a,int b,int k)
{
    if (k==0)
    {
        copy(x,b);
        return;
    }
    if (size[son[x][0]]>=k)
    {
        copy(x,b);
        breakup(son[x][0],a,son[b][0]=++th,k);
        update(b);
    }
    else
    {
        copy(x,a);
        breakup(son[x][1],son[a][1]=++th,b,k-size[son[x][0]]-1);
        update(a);
    }
}
void merge(int x, int a, int b)
{
    if (a==0)copy(b,x);
    else if (b==0)copy(a,x);
    else if (val[a]>val[b])
    {
        copy(a,x);
        merge(son[x][1]=++th,son[a][1],b);
        update(x);
    }
    else
    {
        copy(b,x);
        merge(son[x][0]=++th,a,son[b][0]);
        update(x);
    }

}
void out(int x)
{
    if (son[x][0])out(son[x][0]);
    if (key[x]=='c')dif++;
    printf("%c",key[x]);
    if (son[x][1])out(son[x][1]);
}

int main()
{
    srand(time(NULL));
    scanf("%d",&m);
    int pos,x,y,z,cnt=0,newtree;
    for (int i=1;i<=m;i++)
    {
        scanf("%d",&pos);
        if (pos<=2)cnt++,root[cnt]=root[cnt-1];
        if (pos==1)
        {
            scanf("%d%s",&x,s+1);
            x-=dif;
            newtree=build();
            int a=++th,b=++th,c=++th;
            breakup(root[cnt],a,b,x);
            merge(c,a,newtree);
            merge(root[cnt]=++th,c,b);
        }
        else if (pos==2)
        {
            scanf("%d%d", &x, &y);
            x -= dif, y -= dif;
            int a = ++th, b = ++th;
            breakup(root[cnt], a, b, x - 1);
            int c = ++th, d = ++th;
            breakup(b, c, d, y);
            merge(root[cnt] = ++th, a, d);
        }
        else
        {
            scanf("%d%d%d", &z, &x, &y);
            x -= dif, y -= dif, z -= dif;
            int a = ++th, b = ++th;
            breakup(root[z], a, b, x - 1);
            int c = ++th, d = ++th;
            breakup(b, c, d, y);
            out(c);
            printf("\n");
        }
    }

    return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <ext/rope>

using namespace std;
using namespace __gnu_cxx;

const int maxn=50500;

crope tmp,var[maxn],t;
int n,op,p,c,v,d,curv;
char str[maxn];

int main()
{
  while(scanf("%d",&n)!=EOF)
  {
    curv=0;d=0;
    while(n--)
    {
      scanf("%d",&op);
      if(op==1)
      {
        scanf("%d%s",&p,str);
        p-=d;
        t.insert(p,str);
        var[++curv]=t;
      }
      else if(op==2)
      {
        scanf("%d%d",&p,&c);
        p-=d;c-=d;
        t.erase(p-1,c);
        var[++curv]=t;
      }
      else if(op==3)
      {
        scanf("%d%d%d",&v,&p,&c);
        v-=d;p-=d;c-=d;
        tmp=var[v].substr(p-1,c);
        d+=count(tmp.begin(),tmp.end(),'c');
        cout<<tmp<<endl;
      }
    }
  }
  return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值