zoukankan      html  css  js  c++  java
  • SCOI2014 方伯伯的OJ onlinejudge

    终于用自己的方法水过去了。

    本地测慢的一组要三四秒,一共要十几秒,BZOJ貌似一共只让跑6s,于是就还T着的。

    一开始没看n<=1e8,想的直接splay+map(splay维护名次,map维护对应标号的节点所在位置)

    然后写完看到n的范围 就傻了= =

    百度了一下 splay里面的点要包含一段区间

    想了半天 自己yy了一个做法:

    一开始就一个点:[1,n+2](虚拟节点什么的蛋疼死了,一会+1,一会-1)

    于是需要[l,r]中的p点时,就拆成[l,p-1][p,p][p+1,r],可是这样会不会影响树的形状?

    分析一下,表示区间的点是不会有儿子的,所以我们可以很自然的把这样的点当成普通点看待。

    然后又有一个问题,如何找到这个点在哪个区间里?

    一开始想的建两个splay,另一个splay就是用来干这个的,觉得太麻烦就一直没写。

    最后YY出用set来维护,用set<node(l,r,id)>来维护每个区间,每产生一个区间,就把他扔到set里,然后按r排序

    不难发现,对于x,>=x的第一个r所在的区间一定包含它。然后找到split即可……

    #include<cstdio>
    #include<cstdlib>
    #include<algorithm>
    #include<cstring>
    #include<iostream>
    #include<map>
    #include<set>
    using namespace std;
    
    const int Maxn=400000+10;
    inline int getint(){
        int x=0,f=1;
        char c=getchar();
        for(;!isdigit(c)&&c!='-';c=getchar());
        if(c=='-')f=0;
        for(;isdigit(c);c=getchar())x=x*10+c-'0';
        return f?x:-x;
    }
    inline void getint(int&x){x=getint();}
    struct node{
        int l,r,id;
        inline bool operator<(const node&rhs)const{return r<rhs.r;}
        node(int l,int r,int id):l(l),r(r),id(id){}
    };
    int n,m,a;
    map<int,int>pos;
    set<node> Set;
    typedef set<node>::iterator it;
    typedef int pnode;
    struct Splay{
        int lp[Maxn],rp[Maxn],p[Maxn],l[Maxn],r[Maxn],sz[Maxn],v[Maxn],cnt,tot,root;
        inline void update(int x){
            if(lp[x]==rp[x])sz[x]=sz[l[x]]+sz[r[x]]+1;
            else sz[x]=rp[x]-lp[x]+1;
        }
        inline void split(int x,int mid){// x is a node in Splay Tree and mid is a pointer but not a value
            Set.erase(node(lp[x],rp[x],x));
            int L=0,R=0;
            if(lp[x]!=mid){
                L=++tot;
                l[x]=L;
                p[L]=x;
                lp[L]=lp[x];
                rp[L]=mid-1;
                if(lp[L]==rp[L]){
                    v[L]=lp[x]-1;
                    if(v[L]==n+1)v[L]=0;
                    if(v[L])pos[v[L]]=L;
                }
                else Set.insert(node(lp[L],rp[L],L));
            }
            if(rp[x]!=mid){
                R=++tot;
                r[x]=R;
                p[R]=x;
                lp[R]=mid+1;
                rp[R]=rp[x];
                if(lp[R]==rp[R]){
                    v[R]=rp[x]-1;
                    if(v[R]==n+1)v[R]=0;
                    if(v[R])pos[v[R]]=R;
                }
                else Set.insert(node(lp[R],rp[R],R));
            }
            v[x]=mid-1;
            if(v[x]==n+1)v[x]=0;
            if(v[x])pos[v[x]]=x;
            rp[x]=lp[x]=mid;
            if(L)update(L);
            if(R)update(R);
            update(x);
        }
        inline int find(int x){// x is stand for val
            int t=pos[x];
            if(t)return t;
            it p=Set.lower_bound(node(0,x+1,0));
            t=p->id;
            split(t,x+1);
            return t;
        }
        inline void zig(int x){
            int y=p[x],z=p[y],w=r[x];
            l[y]=w;r[x]=y;
            if(l[z]==y)l[z]=x;
            if(r[z]==y)r[z]=x;
            p[x]=z;p[y]=x;if(w)p[w]=y;
            update(y);update(x);
        }
        inline void zag(int x){
            int y=p[x],z=p[y],w=l[x];
            r[y]=w;l[x]=y;
            if(l[z]==y)l[z]=x;
            if(r[z]==y)r[z]=x;
            p[x]=z;p[y]=x;if(w)p[w]=y;
            update(y);update(x);
        }
        inline void rotate(int x){
            if(l[p[x]]==x)zig(x);else zag(x);
        }
        inline void splay(int x,int FA){
            for(;p[x]!=FA;){
                int y=p[x],z=p[y];
                if(z!=FA){
                    if( (l[y]==x)^(l[z]==y) )rotate(x);else rotate(y);
                }
                rotate(x);
            }
            if(!FA)root=x;
        }
        inline void init(){
            cnt=tot=sz[0]=0;
            root=++tot=1;
            lp[root]=1,rp[root]=n+2;
            Set.insert(node(1,n+2,root));
            update(root);
        }
        int kth(int o,int k){
            if(rp[o]!=lp[o]){
                split(o,lp[o]+k-1);
                return o;
            }
            int s=sz[l[o]];
            if(s+1==k)return o;
            if(s+1<k)return kth(r[o],k-s-1);
            return kth(l[o],k);
        }
        inline int deal(){
            if(m==2)
            m=2;
            int x,y,opt;
            getint(opt);
            if(opt==1){
                getint(x),getint(y);
                x-=a,y-=a;
                int o=find(x);
                v[o]=y;
                pos[x]=0;
                pos[y]=o;
                splay(o,0);
                return a=sz[l[o]];
            }
            else if(opt==2||opt==3){
                getint(x);x-=a;
                x=find(x);
                splay(x,0);
                int rk=sz[l[x]];
                if(rk==n&&opt==3)return a=rk;
                if(rk==1&&opt==2)return a=rk;
                int lt=kth(root,rk-1 +1),rt=kth(root,rk+1 +1);//for the static 1
                splay(lt,0);
                splay(rt,lt);
                l[rt]=0;
                update(rt);
                update(lt);
                int fst,snd;
                if(opt==2)fst=kth(root,1),snd=kth(root,2);
                else fst=kth(root,n),snd=kth(root,n+1);//for 1 has been killed
                splay(fst,0);
                splay(snd,fst);
                l[snd]=x;
                p[x]=snd;
                update(snd);
                update(fst);
                return a=rk;
            }
            else {
                getint(x);x-=a;
                return a=v[kth(root,x+1)];
            }
        }
    }sp;
    int main(){
        freopen("onlinejudge.in","r",stdin);
        freopen("onlinejudge.out","w",stdout);
        scanf("%d%d",&n,&m);
        sp.init();
        for(;m--;)printf("%d
    ",sp.deal());
        return 0;
    }
  • 相关阅读:
    Linux:打印(输出)所有的列(awk, $0)
    Linux:批量修改分隔符(awk、BEGIN、FS、OFS、print、tr命令)
    vcf格式文件转化为Excel(csv)格式文件(R语言的write.csv,write.table功能,Excel表的文件导入功能)
    Linux追加文件内容并在内容前加上该文件名(awk, FILENAME功能妙用)
    斯坦福大学公开课机器学习:监督学习在行人检测的应用(supervised learning for pedestrian detection)
    斯坦福大学公开课机器学习:梯度下降运算的学习率a(gradient descent in practice 2:learning rate alpha)
    斯坦福大学公开课机器学习:梯度下降运算的特征缩放(gradient descent in practice 1:feature scaling)
    解决invalid record found in VCF4 file (at least 8 tab-delimited fields expected)问题,批量修改空格改为制表格格式
    vcf文件(call variants得来的)怎么看变异是纯合还是杂合的
    剑指offer四十八之不用加减乘除做加法
  • 原文地址:https://www.cnblogs.com/showson/p/4284413.html
Copyright © 2011-2022 走看看