CVS

题目连接:

http://acm.timus.ru/problem.aspx?space=1&num=1992

Description

Yoda: Visit I will the cloners on Kamino... And see this army they have created for the Republic.

Cloners from the Kamino planet breed some of the finest clones. Such good results are due to the careful management over the clones’ evolution. The Kaminuans are now busy working out a new study technology that lets increase the clones’ effectiveness. The cloners have come up with a new control system CVS (Clone Version System) that makes managing the progress of experiments easier. The system is quite simple to use.

The Kaminuans have some set of educational programs at their disposal. A clone’s effectiveness depends on which programs and in which order he has learned. The Kaminuans can teach any clone a program as long as this clone hasn’t learned it already.

To make the experiments even easier to conduct, the Kaminuans enabled canceling the changes made by the last program the clone has learned. In this case, the clone’s knowledge returns to the level when the program hasn’t yet been studied. Then this clone can study this program in the future. You can cancel programs at any time unless the clone is at the basic knowledge level.

Besides the ‘roll back’ function, a clone can ‘re-learn’ a program. If one cancels some program by mistake, he can cancel the cancellation. The CVS keeps record of each clone’s canceled programs. After a program is canceled, the CVS adds another record. After a clone re-learn a program, the record is deleted. If a clone learn (not relearn) a program, all cancellation record history of this clone is deleted. You can use the re-learn function as long as the record history for this clone contains any records.

Finally, the system has a ‘clone’ option. If a Kaminuan likes the current variant of a clone, he can clone the clone, that is, create a new clone with the same sequence of taught programs and cancellation history.

Initially the Kaminuans have a single clone with basic knowledge. Help them analyze the progress of the experiments.

Input

The first line of the input contains numbers n — the number of queries — and m — the number of educational programs (1 ≤ n, m ≤ 5·10 5). Each of the following n lines has one of the formats given below.

learn ci pi. Teach clone ci program pi (1 ≤ pi ≤ m).

rollback ci. Cancel the last learned program for clone ci.

relearn ci. Apply ‘re-learn’ function to clone ci.

clone ci. Clone the clone ci.

check ci. Display the last program clone ci has learned and knows at the moment.

It is guaranteed that rollback won’t be applied to the clone that is at the basic knowledge level. learn is always applied with the program a clone doesn’t already know. relearn is only applied if the cancellation history of a clone is not empty. It is also guaranteed that only the clones that already exist can occur in the queries. The numbers are assigned to the clones in the order the clones appear. The Kaminuans started their experiments from clone number one.

Output

For each check ci query display the result on a single line. If some clone has only basic knowledge, print basic, otherwise print the number of the last learned program.

Sample Input

9 10

learn 1 5

learn 1 7

rollback 1

check 1

clone 1

relearn 2

check 2

rollback 1

check 1

Sample Output

5

7

basic

Hint

题意

有五个操作

learn x y,让x学习y知识

rollback x,让x遗忘最后一个学习的知识

check x,问x最后学习的是啥

relearn x,让x学习一个最后一个遗忘的知识

clone x,复制一个

题解:

实际上就是维护两个可持久化的栈,因为有克隆和回到之前的操作嘛

我们去维护两棵树,一个是学习的树,一个是遗忘的树

然后根据标记去维护就好了

这道题比较毒瘤,必须加读入挂才能过……

代码

#include<bits/stdc++.h>
using namespace std;
namespace fastIO{
#define BUF_SIZE 100000
#define OUT_SIZE 100000
#define ll long long
//fread->read
bool IOerror=0;
inline char nc(){
static char buf[BUF_SIZE],*p1=buf+BUF_SIZE,*pend=buf+BUF_SIZE;
if (p1==pend){
p1=buf; pend=buf+fread(buf,1,BUF_SIZE,stdin);
if (pend==p1){IOerror=1;return -1;}
//{printf("IO error!\n");system("pause");for (;;);exit(0);}
}
return *p1++;
}
inline bool blank(char ch){return ch==' '||ch=='\n'||ch=='\r'||ch=='\t';}
inline void read(int &x){
bool sign=0; char ch=nc(); x=0;
for (;blank(ch);ch=nc());
if (IOerror)return;
if (ch=='-')sign=1,ch=nc();
for (;ch>='0'&&ch<='9';ch=nc())x=x*10+ch-'0';
if (sign)x=-x;
}
inline void read(ll &x){
bool sign=0; char ch=nc(); x=0;
for (;blank(ch);ch=nc());
if (IOerror)return;
if (ch=='-')sign=1,ch=nc();
for (;ch>='0'&&ch<='9';ch=nc())x=x*10+ch-'0';
if (sign)x=-x;
}
inline void read(double &x){
bool sign=0; char ch=nc(); x=0;
for (;blank(ch);ch=nc());
if (IOerror)return;
if (ch=='-')sign=1,ch=nc();
for (;ch>='0'&&ch<='9';ch=nc())x=x*10+ch-'0';
if (ch=='.'){
double tmp=1; ch=nc();
for (;ch>='0'&&ch<='9';ch=nc())tmp/=10.0,x+=tmp*(ch-'0');
}
if (sign)x=-x;
}
inline void read(char *s){
char ch=nc();
for (;blank(ch);ch=nc());
if (IOerror)return;
for (;!blank(ch)&&!IOerror;ch=nc())*s++=ch;
*s=0;
}
inline void read(char &c){
for (c=nc();blank(c);c=nc());
if (IOerror){c=-1;return;}
}
//getchar->read
inline void read1(int &x){
char ch;int bo=0;x=0;
for (ch=getchar();ch<'0'||ch>'9';ch=getchar())if (ch=='-')bo=1;
for (;ch>='0'&&ch<='9';x=x*10+ch-'0',ch=getchar());
if (bo)x=-x;
}
inline void read1(ll &x){
char ch;int bo=0;x=0;
for (ch=getchar();ch<'0'||ch>'9';ch=getchar())if (ch=='-')bo=1;
for (;ch>='0'&&ch<='9';x=x*10+ch-'0',ch=getchar());
if (bo)x=-x;
}
inline void read1(double &x){
char ch;int bo=0;x=0;
for (ch=getchar();ch<'0'||ch>'9';ch=getchar())if (ch=='-')bo=1;
for (;ch>='0'&&ch<='9';x=x*10+ch-'0',ch=getchar());
if (ch=='.'){
double tmp=1;
for (ch=getchar();ch>='0'&&ch<='9';tmp/=10.0,x+=tmp*(ch-'0'),ch=getchar());
}
if (bo)x=-x;
}
inline void read1(char *s){
char ch=getchar();
for (;blank(ch);ch=getchar());
for (;!blank(ch);ch=getchar())*s++=ch;
*s=0;
}
inline void read1(char &c){for (c=getchar();blank(c);c=getchar());}
//scanf->read
inline void read2(int &x){scanf("%d",&x);}
inline void read2(ll &x){
#ifdef _WIN32
scanf("%I64d",&x);
#else
#ifdef __linux
scanf("%lld",&x);
#else
puts("error:can't recognize the system!");
#endif
#endif
}
inline void read2(double &x){scanf("%lf",&x);}
inline void read2(char *s){scanf("%s",s);}
inline void read2(char &c){scanf(" %c",&c);}
inline void readln2(char *s){gets(s);}
//fwrite->write
struct Ostream_fwrite{
char *buf,*p1,*pend;
Ostream_fwrite(){buf=new char[BUF_SIZE];p1=buf;pend=buf+BUF_SIZE;}
void out(char ch){
if (p1==pend){
fwrite(buf,1,BUF_SIZE,stdout);p1=buf;
}
*p1++=ch;
}
void print(int x){
static char s[15],*s1;s1=s;
if (!x)*s1++='0';if (x<0)out('-'),x=-x;
while(x)*s1++=x%10+'0',x/=10;
while(s1--!=s)out(*s1);
}
void println(int x){
static char s[15],*s1;s1=s;
if (!x)*s1++='0';if (x<0)out('-'),x=-x;
while(x)*s1++=x%10+'0',x/=10;
while(s1--!=s)out(*s1); out('\n');
}
void print(ll x){
static char s[25],*s1;s1=s;
if (!x)*s1++='0';if (x<0)out('-'),x=-x;
while(x)*s1++=x%10+'0',x/=10;
while(s1--!=s)out(*s1);
}
void println(ll x){
static char s[25],*s1;s1=s;
if (!x)*s1++='0';if (x<0)out('-'),x=-x;
while(x)*s1++=x%10+'0',x/=10;
while(s1--!=s)out(*s1); out('\n');
}
void print(double x,int y){
static ll mul[]={1,10,100,1000,10000,100000,1000000,10000000,100000000,
1000000000,10000000000LL,100000000000LL,1000000000000LL,10000000000000LL,
100000000000000LL,1000000000000000LL,10000000000000000LL,100000000000000000LL};
if (x<-1e-12)out('-'),x=-x;x*=mul[y];
ll x1=(ll)floor(x); if (x-floor(x)>=0.5)++x1;
ll x2=x1/mul[y],x3=x1-x2*mul[y]; print(x2);
if (y>0){out('.'); for (size_t i=1;i<y&&x3*mul[i]<mul[y];out('0'),++i); print(x3);}
}
void println(double x,int y){print(x,y);out('\n');}
void print(char *s){while (*s)out(*s++);}
void println(char *s){while (*s)out(*s++);out('\n');}
void flush(){if (p1!=buf){fwrite(buf,1,p1-buf,stdout);p1=buf;}}
~Ostream_fwrite(){flush();}
}Ostream;
inline void print(int x){Ostream.print(x);}
inline void println(int x){Ostream.println(x);}
inline void print(char x){Ostream.out(x);}
inline void println(char x){Ostream.out(x);Ostream.out('\n');}
inline void print(ll x){Ostream.print(x);}
inline void println(ll x){Ostream.println(x);}
inline void print(double x,int y){Ostream.print(x,y);}
inline void println(double x,int y){Ostream.println(x,y);}
inline void print(char *s){Ostream.print(s);}
inline void println(char *s){Ostream.println(s);}
inline void println(){Ostream.out('\n');}
inline void flush(){Ostream.flush();}
//puts->write
char Out[OUT_SIZE],*o=Out;
inline void print1(int x){
static char buf[15];
char *p1=buf;if (!x)*p1++='0';if (x<0)*o++='-',x=-x;
while(x)*p1++=x%10+'0',x/=10;
while(p1--!=buf)*o++=*p1;
}
inline void println1(int x){print1(x);*o++='\n';}
inline void print1(ll x){
static char buf[25];
char *p1=buf;if (!x)*p1++='0';if (x<0)*o++='-',x=-x;
while(x)*p1++=x%10+'0',x/=10;
while(p1--!=buf)*o++=*p1;
}
inline void println1(ll x){print1(x);*o++='\n';}
inline void print1(char c){*o++=c;}
inline void println1(char c){*o++=c;*o++='\n';}
inline void print1(char *s){while (*s)*o++=*s++;}
inline void println1(char *s){print1(s);*o++='\n';}
inline void println1(){*o++='\n';}
inline void flush1(){if (o!=Out){if (*(o-1)=='\n')*--o=0;puts(Out);}}
struct puts_write{
~puts_write(){flush1();}
}_puts;
inline void print2(int x){printf("%d",x);}
inline void println2(int x){printf("%d\n",x);}
inline void print2(char x){printf("%c",x);}
inline void println2(char x){printf("%c\n",x);}
inline void print2(ll x){
#ifdef _WIN32
printf("%I64d",x);
#else
#ifdef __linux
printf("%lld",x);
#else
puts("error:can't recognize the system!");
#endif
#endif
}
inline void println2(ll x){print2(x);printf("\n");}
inline void println2(){printf("\n");}
#undef ll
#undef OUT_SIZE
#undef BUF_SIZE
};
using namespace fastIO;
const int maxn = 5e5+7;
int pos1[maxn],pos2[maxn];
int fa[maxn],fa2[maxn];
vector<int>G1[maxn],G2[maxn];
int T1[maxn],T2[maxn];
int tot1=0,tot2=0,num=2;
void learn()
{
int x,y;
scanf("%d%d",&x,&y);
T1[++tot1]=y;
G1[pos1[x]].push_back(tot1);
fa[tot1]=pos1[x];
pos1[x]=tot1;
}
void rollback()
{
int x;
scanf("%d",&x);
T2[++tot2]=pos1[x];
G2[pos2[x]].push_back(tot2);
fa2[tot2]=pos2[x];
pos2[x]=tot2;
pos1[x]=fa[pos1[x]];
}
void check()
{
int x;
scanf("%d",&x);
if(pos1[x]==0)printf("basic\n");
else printf("%d\n",T1[pos1[x]]);
}
void clone()
{
int x;
scanf("%d",&x);
pos1[num]=pos1[x],pos2[num]=pos2[x];
num++;
}
void relearn()
{
int x;
scanf("%d",&x);
pos1[x]=T2[pos2[x]];
pos2[x]=fa2[pos2[x]];
}
char s[15];
int main()
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
read1(s);
if(s[0]=='l')learn();
if(s[0]=='r'&&s[1]=='o')rollback();
if(s[0]=='c'&&s[1]=='h')check();
if(s[0]=='c'&&s[1]=='l')clone();
if(s[0]=='r'&&s[1]=='e')relearn();
}
}

URAL 1992 CVS的更多相关文章

  1. URAL 1992 CVS 可持久化链栈

    http://www.cnblogs.com/tedzhao/archive/2008/11/12/1332112.html 看这篇的链表部分的介绍应该就能理解“可持久化”了 动态分配内存的会T,只能 ...

  2. URAL 1992 CVS 链表

    不更改链表结构,只是添加节点,没有删除节点.通过记录和更改标记来模拟题意的插入和删除,复制 指针模拟链表: 预开指针,存在M[]中,可以提高效率 #include<functional> ...

  3. URAL 1992

    CVS Description Yoda: Visit I will the cloners on Kamino... And see this army they have created for ...

  4. 版本控制工具比较-CVS,SVN,GIT

    首先介绍几个版本控制软件相互比较的重要依据: a.版本库模型(Repository model):描述了多个源码版本库副本间的关系,有客户端/服务器和分布式两种模式.在客户端/服务器模式下,每一用户通 ...

  5. 【Java EE 学习 43】【SVN版本控制工具】【CVS版本控制工具】

    一.SVN SVN服务器下载地址:https://subversion.apache.org/ 1.什么是版本控制:版本控制是维护工程蓝图的标准做法,能追踪工程蓝图从诞生一直到定案的过程.是一种记录若 ...

  6. cvs update后输出的文件标志 和 update常用的几个参数

    (1)update 和 checkout 在执行中,会为每个文件打印一行提示信息,文件的状态通过前面的单个字符指明:       U file        文件按要求从仓库得到更新.用在那些仓库里面 ...

  7. BAT 快速删除CVS文件和拷贝最近修改文件的目录结构

    相信大家在操作大量文件的的时候,经常会遇到一些手动很难操作的情况 比如有CVS版本控制下每个文件夹下都有一个CVS文件夹,一个个手工删除肯定很费劲,我们都是懒人,还是用工具解决吧.不用重新写程序,直接 ...

  8. SVN和CVS的区别

    对版本控制就有了一定的理解,同时也应该知道SVN与CVS是比较流行的两款SCM工具.那么到底这两款工具有什么区别呢? 1.版本编号方面 例如,我们的版本库为A,其中有文件a,b,c. 在SVN中,新版 ...

  9. 后缀数组 POJ 3974 Palindrome && URAL 1297 Palindrome

    题目链接 题意:求给定的字符串的最长回文子串 分析:做法是构造一个新的字符串是原字符串+反转后的原字符串(这样方便求两边回文的后缀的最长前缀),即newS = S + '$' + revS,枚举回文串 ...

随机推荐

  1. USB各种模式 解释

    1.MTP: 通过MTP这种技术,可以把音乐传到手机里.有了U盘功能为什么还要多此一举呢?因为版权问题,MTP可以把权限文件从电脑上导过去:如果只使用手机的U盘功能,把歌的文件拷过去之后,没有权限文件 ...

  2. 省市区ajax联动

    function setCity1(){ var areaId1 = $('#areaId1').val(); var cityId1 = $('#cityId1'); var cityOpt = $ ...

  3. git 还原到指定版本号

      git clone git branch -r --contains 88b92060224e96ef209565fa75c816eb9b0fae8e git checkout origin/re ...

  4. FAQ1: 列表索引和切片问题

    问题1. 超过列表成员个数的索引访问列表会出现IndexError错误,但是如果用切片去访问就不会报错,而是返回一个空列表.同样元组也是. >>> a=[1,2,3,4] >& ...

  5. acm专题---键树

    题目来源:http://hihocoder.com/problemset/problem/1014?sid=982973 #1014 : Trie树 时间限制:10000ms 单点时限:1000ms ...

  6. 20165301 2017-2018-2 《Java程序设计》第八周学习总结

    20165301 2017-2018-2 <Java程序设计>第八周学习总结 教材学习内容总结 第十二章:Java多线程机制 进程与线程 操作系统与进程:进程是程序的一次动态执行过程. 进 ...

  7. hive学习(六) 参数和动态分区

    1.hive 参数.变量 1.1hive的命名空间: hive当中的参数.变量,都是以命名空间开头  

  8. 小甲鱼C++笔记(上)1-24

    一 OO思想:每个对象都是一个完整的独立的个体,由相关的属性和行为组合与外界分隔 OO思想的特点:1封装 把对象的属性和方法结合成一个独立的系统单位,并尽可能隐藏内部细节 2抽象 对一类公共问题进行统 ...

  9. [实战]MVC5+EF6+MySql企业网盘实战(15)——逻辑重构2

    写在前面 上篇文章修改文件上传的逻辑,这篇修改下文件下载的逻辑. 系列文章 [EF]vs15+ef6+mysql code first方式 [实战]MVC5+EF6+MySql企业网盘实战(1) [实 ...

  10. python平均值和加权平均值

    In [15]: import numpy as np In [16]: a=(70,80,60) In [17]: np.mean(a) #平均值 Out[17]: 70.0 In [18]: np ...