zoukankan      html  css  js  c++  java
  • 3678: wangxz与OJ

    Description

    某天,wangxz神犇来到了一个信息学在线评测系统(Online Judge)。由于他是一位哲♂学的神犇,所以他不打算做题。他发现这些题

    目呈线性排列,被标记为1~n号,每道题都有一个难度值(可以<=0)。他决定与这些题目玩♂耍。

    1、他可以在某个位置插♂入一些难度值特定的题目。

    2、他可以吃♂掉(删除)一段题目。

    3、他可以查询某个位置的题目的难度值。

    维护一个初始有n个元素的序列(标记为1~n号元素),支持以下操作:

    0 p a b (0<=p<=当前序列元素个数) (a<=b) 在p位置和p+1位置之间插入整数:a,a+1,a+2,...,b-1,b。若p为0,插在序列最前面;

    1 a b (1<=a<=b<=当前序列元素个数) 删除a,a+1,a+2,...,b-1,b位置的元素;

    2 p (1<=p<=当前序列元素个数) 查询p位置的元素。

    Input

    输入第一行包括两个正整数n(1<=n<=20000),m(1<=m<=20000),代表初始序列元素个数和操作个数。

    接下来n个整数,为初始序列元素。

    接下来m行,每行第一个为整数sym,

    若sym=0,接下来有一个非负整数p,两个整数a,b;

    若sym=1,接下来有两个正整数a,b;

    若sym=2,接下来有一个正整数p;

    p、x、y的含义及范围见题目描述。

    在任何情况下,保证序列中的元素总数不超过100000。

    保证题目涉及的所有数在int内。

    Output

    对每个sym=2,输出一行,包括一个整数,代表询问位置的元素。

    Sample Input

    5 3
    1 2 3 4 5
    0 2 1 4
    1 3 8
    2 2

    Sample Output

    2

    HINT

    Source

    From LiZitong

    splay题,用到了动态开点

    #include<bits/stdc++.h>
    using namespace std;
    
    struct tree{
        int len,size,num,ch[2],fa;
    }t[120005];
    
    int root,tot,n,m;
    
    void pushup(int x){
        t[x].size=t[t[x].ch[0]].size+t[t[x].ch[1]].size+t[x].len;
    }
    
    int chk(int x){
        return t[t[x].fa].ch[1]==x;
    }
    
    void rotate(int x){
        int y=t[x].fa,z=t[y].fa,k=chk(x),w=t[x].ch[k^1];
        t[y].ch[k]=w;
        t[w].fa=y;
        t[z].ch[chk(y)]=x;
        t[x].fa=z;
        t[x].ch[k^1]=y;
        t[y].fa=x;
        pushup(y);
        pushup(x);
    }
    
    void splay(int x,int goal=0){
        while(t[x].fa!=goal){
            int y=t[x].fa,z=t[y].fa;
            if(z!=goal) if(chk(x)==chk(y)) rotate(y);
            else rotate(x);
            rotate(x);
        }
        if(!goal) root=x;
    }
    
    int kth(int k){
        int cur=root;
        while(1){
            if(t[t[cur].ch[0]].size>=k) cur=t[cur].ch[0];
            else if(t[t[cur].ch[0]].size+t[cur].len<k) k-=t[t[cur].ch[0]].size+t[cur].len,cur=t[cur].ch[1];
            else {
                k-=t[t[cur].ch[0]].size;
                if(k!=1){
                    t[++tot].fa=cur;
                    t[tot].ch[0]=t[cur].ch[0];
                    t[tot].num=t[cur].num;
                    t[t[cur].ch[0]].fa=tot;
                    t[tot].len=k-1;
                    t[cur].ch[0]=tot;
                    pushup(tot);
                }
                if(k!=t[cur].len){
                    t[++tot].fa=cur;
                    t[tot].ch[0]=t[cur].ch[1];
                    t[tot].num=t[cur].num+k;
                    t[t[cur].ch[1]].fa=tot;
                    t[tot].len=t[cur].len-k;
                    t[cur].ch[1]=tot;
                    pushup(tot);
                }
                t[cur].len=1;t[cur].num+=k-1;
                return cur;
            }
        }
    }
    
    int build(int l,int r){
        int mid=(l+r)>>1;
        if(l!=mid) t[mid].ch[0]=build(l,mid-1),t[t[mid].ch[0]].fa=mid;
        if(mid!=r) t[mid].ch[1]=build(mid+1,r),t[t[mid].ch[1]].fa=mid;
        pushup(mid);
        return mid;
    }
    
    int split(int l,int r){
        l=kth(l);r=kth(r+2);
        splay(l);
        splay(r,l);
        return r;
    }
    
    int main(){
        scanf("%d%d",&n,&m);
        t[1].size=t[1].len=1;
        for(int i=1;i<=n;i++) scanf("%d",&t[i+1].num),t[i+1].size=t[i+1].len=1;
        t[n+2].size=t[n+2].len=1;
        tot=n+2;
        root=build(1,n+2);
        while(m--){
            int opt;
            scanf("%d",&opt);
            switch(opt){
                case 0:{
                    int p,a,b;
                    scanf("%d%d%d",&p,&a,&b);
                    int cur=split(p+1,p);
                    t[++tot].fa=cur;t[cur].ch[0]=tot;
                    t[tot].num=a;t[tot].len=t[tot].size=b-a+1;
                    pushup(cur);pushup(root);                
                    break;
                }
                case 1:{
                    int a,b;
                    scanf("%d%d",&a,&b);
                    int cur=split(a,b);
                    t[t[cur].ch[0]].fa=t[cur].ch[0]=0;
                    pushup(cur);
                    pushup(root);                
                    break;
                }
                case 2:{
                    int p;scanf("%d",&p);
                    int cur=split(p,p);
                    printf("%d
    ",t[t[cur].ch[0]].num);                
                    break;
                }
    
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    常见RGB透明度对照表在这
    Android节假日图标动态替换方案
    用两个栈实现队列
    从头到尾打印链表 (链表/栈)
    MySQL常用函数
    找出数组中重复的数字
    两数之和
    java的list的几种排序写法整理(sort的用法)
    Java知识目录
    通过关键词来推荐话题
  • 原文地址:https://www.cnblogs.com/plysc/p/11360087.html
Copyright © 2011-2022 走看看