CVS (URAL 1992 可持久化的链表)

介绍了一个克隆人训练系统,该系统通过不同的操作如学习新技能、撤销最近学习的技能等来提高克隆人的效率。文章详细解释了系统的运作方式,并提供了一段C++代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

CVS
Time Limit: 1000MS Memory Limit: 65536KB 64bit IO Format: %I64d & %I64u

 Status

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 ≤  nm ≤ 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  c i 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

input output
9 10
learn 1 5
learn 1 7
rollback 1
check 1
clone 1
relearn 2
check 2
rollback 1
check 1
5
7
basic

Source

Problem Author: Egor Shchelkonogov 


题意:开始有1个克隆人,现在有5种操作,learn ci pi指让ci克隆人学会技能pi,rollback ci指删除ci克隆人学会的最近一个技能并记下删除记录,relearn ci指让ci克隆人重新学习之前删除的技能,clone ci指再克隆一个ci,check ci指输出ci克隆人当前最近学的技能。

思路:关键是在clone的时候需要有好的方法,如果直接重新复制那肯定复杂度太大会T,然后就上网学习了一下别人链表的做法,这里我用的链式向前星。head所维护的链表用来记录克隆人已经学会的技能,head2用来维护回滚历史。另外用G++交会超时=-=

参考:http://www.cnblogs.com/tedzhao/archive/2008/11/12/1332112.html

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <string>
#include <map>
#include <stack>
#include <vector>
#include <set>
#include <queue>
#pragma comment (linker,"/STACK:102400000,102400000")
#define pi acos(-1.0)
#define eps 1e-6
#define lson rt<<1,l,mid
#define rson rt<<1|1,mid+1,r
#define FRE(i,a,b)  for(i = a; i <= b; i++)
#define FREE(i,a,b) for(i = a; i >= b; i--)
#define FRL(i,a,b)  for(i = a; i < b; i++)
#define FRLL(i,a,b) for(i = a; i > b; i--)
#define mem(t, v)   memset ((t) , v, sizeof(t))
#define sf(n)       scanf("%d", &n)
#define sff(a,b)    scanf("%d %d", &a, &b)
#define sfff(a,b,c) scanf("%d %d %d", &a, &b, &c)
#define pf          printf
#define DBG         pf("Hi\n")
typedef long long ll;
using namespace std;

#define INF 0x3f3f3f3f
#define mod 1000000009
const int maxn = 500050;
const int MAXN = 2005;
const int MAXM = 200010;
const int N = 1005;

struct Node
{
    int val;
    int next;
}node[2*maxn];

int head[maxn],head2[maxn];
int cnt,n,m,num;

void init()
{
    num=1;//cloners' number
    cnt=0;
}

void addnode(int id,int w)
{
    node[cnt].val=w;
    node[cnt].next=head[id];
    head[id]=cnt++;
}

void addnode2(int id,int w)
{
    node[cnt].val=w;
    node[cnt].next=head2[id];
    head2[id]=cnt++;
}

int main()
{
#ifndef ONLINE_JUDGE
    freopen("C:/Users/lyf/Desktop/IN.txt","r",stdin);
#endif
    int i,j,id,w;
    char str[10];
    while (~sff(n,m))
    {
        init();
        head[num]=head2[num]=-1;
        for (i=0;i<n;i++)
        {
            scanf("%s",str);
            if (str[0]=='l')
            {
                sff(id,w);
                addnode(id,w);
                head2[id]=-1;
            }
            else if (str[0]=='r')
            {
                sf(id);
                if (str[1]=='o')    //回滚
                {
                    addnode2(id,node[head[id]].val); //记录历史
                    head[id]=node[head[id]].next;
                }
                else                //重新学习
                {
                    addnode(id,node[head2[id]].val);
                    head2[id]=node[head2[id]].next;
                }
            }
            else if (str[0]=='c')
            {
                sf(id);
                if (str[1]=='h')
                {
                    if (head[id]==-1) pf("basic\n");
                    else pf("%d\n",node[head[id]].val);
                }
                else
                {
                    num++;
                    head[num]=head[id];
                    head2[num]=head2[id];
                }
            }
        }
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值