zoukankan      html  css  js  c++  java
  • 【OI】操作树

    操作数,一般用来做那些对数列进行添加、撤销操作的题。

    假设一开始有一个空数列,有三个操作

    (1)在数列后加一个数

    (2)求数列中某位置的值

    (3)撤销掉最后进行的若干次操作(1和3)

    考虑建一棵树,1操作则为在当前节点下新加一个节点,2操作求数列k位置值,则为从根节点到当前节点k个节点的位置的节点

    3操作撤销掉最后进行的k次操作则为回溯k个节点,同时记录回溯前的当前节点和回溯后的当前节点。

    所以每次进行查询的时候,先从当前节点找父亲,一直找到根节点,记录节点个数,然后节点个数-k得到当前节点到要查询的节点的距离。

    撤销操作的时候,父亲是1操作的节点就往上找父亲,父亲是3操作节点就跳到那个3操作回溯之前的那个“当前节点”

    例如这道题:

    总时间限制: 
    10000ms
     
    单个测试点时间限制: 
    1000ms
     
    内存限制: 
    262144kB
    描述

    给一个空数列,有M次操作,每次操作是以下三种之一:

    (1)在数列后加一个数

    (2)求数列中某位置的值

    (3)撤销掉最后进行的若干次操作(1和3)

    输入
    第一行一个正整数M。
    接下来M行,每行开头是一个字符,若该字符为'A',则表示一个加数操作,接下来一个整数x,表示在数列后加一个整数x;若该字符为'Q',则表示一个询问操作,接下来一个整数x,表示求x位置的值;若该字符为'U',则表示一个撤销操作,接下来一个整数x,表示撤销掉最后进行的若干次操作。
    输出
    对每一个询问操作单独输出一行,表示答案。
    样例输入
    9
    A 1
    A 2
    A 3
    Q 3
    U 1
    A 4
    Q 3
    U 2
    Q 3
    样例输出
    3
    4
    3
    提示
    1<=M<=10^5,输入保证合法,且所有整数可用带符号32位整型存储。
    #include <cstdio>
    #include <iostream>
    
    const int MaxN = 100001;
    int fa[MaxN];
    //bool edge[MaxN][MaxN];
    int n;
    int V[MaxN];
    int back[MaxN];
    
    int main()
    {
        scanf("%d",&n);
        
        int now_node;
        
        char XX;
        std::cin>>XX;
        int xx;
        scanf("%d",&xx);
        now_node = 1;
        
        int node_cnt = 1;
        V[node_cnt] = xx;
        
        for(int l = 2; l <= n; l++){
            char X;
            std::cin>>X;
            if(X == 'A'){
                int nx;
                scanf("%d",&nx);
                V[++node_cnt] = nx;
                fa[node_cnt] = now_node;
                //edge[now_node][node_cnt] = 1;
                now_node = node_cnt;
                
            }
            else if(X == 'U'){
                int nx;
                scanf("%d",&nx);
                int last_node = now_node;
                for(int i = 1; i <= nx; i++){
                    if(!back[now_node])
                        now_node = fa[now_node];
                    else
                        now_node = back[now_node];
                    
                }
                back[now_node] = last_node;
                
            }
            else if(X == 'Q'){
                int nx;
                scanf("%d",&nx);
                
                int count = 0;
                int tmp = now_node;
                while(1){
                    if(!fa[tmp]){
                        break;
                    }
                    tmp = fa[tmp];
                    count++;
                }
                count = count - nx;
                tmp = now_node;
                for(int i = 1; i <= count; i++){
                    tmp = fa[tmp];
                }
                printf("%d
    ",V[tmp]);
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    GhostBSD 3.0RC3,基于GNOME的FreeBSD
    Nagios 3.4.3 发布,企业级监控系统
    Jolokia 1.0.6 发布, JMX远程访问方法
    微软希望开发人员不要使 WebKit 成为新版 IE6
    Kwort Linux 3.5 正式版发布
    EJDB 1.0.24 发布,嵌入式 JSON 数据库引擎
    Pale Moon 15.3 Firefox“苍月”优化版发布
    Galera Load Balancer 0.8.1 发布
    SmartSVN V7.5 正式发布
    PostgresQL建立索引如何避免写数据锁定
  • 原文地址:https://www.cnblogs.com/dudujerry/p/11619014.html
Copyright © 2011-2022 走看看