• bzoj1861[Zjoi2006]Book 书架


    bzoj1861[Zjoi2006]Book 书架

    题意:

    维护一个序列,支持移动元素,查询元素是第几个,查询第k个元素编号。

    题解:

    可以用treap和splay,我写的是splay。移动元素就是先删一个节点在将这个节点插入到对应位置,注意各种分操作(如splay、find)的次序性。反思:本弱又WA又T,最后自己造了一个极限数据发现死循环了,对着大数据调了半天才发现是分操作次序不当导致错误。

    代码:

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 #define inc(i,j,k) for(int i=j;i<=k;i++)
     5 #define maxn 80100
     6 using namespace std;
     7 
     8 int ch[maxn][2],fa[maxn],v[maxn],sz[maxn],pos[maxn],root,book[maxn],tot,n,m;
     9 inline int read(){
    10     char ch=getchar(); int f=1,x=0;
    11     while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();};
    12     while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
    13     return f*x;
    14 }
    15 inline void update(int x){sz[x]=sz[ch[x][0]]+sz[ch[x][1]]+1;}
    16 void rotate(int x){
    17     if(!x||!fa[x])return; int a=fa[x],b=fa[fa[x]]; bool c=x==ch[fa[x]][1],d=a==ch[fa[a]][1];
    18     if(b)ch[b][d]=x; fa[x]=b; ch[a][c]=ch[x][!c]; if(ch[x][!c])fa[ch[x][!c]]=a; ch[x][!c]=a; fa[a]=x;
    19     update(a); update(x); if(b)update(b);
    20 }
    21 void splay(int x,int y){
    22     if(x==y)return; int z=fa[y];
    23     while(fa[x]!=z){
    24         if(fa[x]!=y)(x==ch[fa[x]][1])^(fa[x]==ch[fa[fa[x]]][1])?rotate(x):rotate(fa[x]);
    25         rotate(x);
    26     }
    27     if(root==y)root=x;
    28 }
    29 void build(int x,int l,int r){
    30     int mid=l+r>>1; v[x]=book[mid]; pos[book[mid]]=x;
    31     if(l<=mid-1)ch[x][0]=++tot,build(ch[x][0],l,mid-1),fa[ch[x][0]]=x;
    32     if(mid+1<=r)ch[x][1]=++tot,build(ch[x][1],mid+1,r),fa[ch[x][1]]=x;
    33     update(x);
    34 }
    35 int querynum(int x,int k){
    36     if(k<=sz[ch[x][0]])return querynum(ch[x][0],k);
    37     if(k==sz[ch[x][0]]+1)return x;
    38     return querynum(ch[x][1],k-sz[ch[x][0]]-1);
    39 }
    40 int queryrank(int x){
    41     splay(x,root); return sz[ch[x][0]];
    42 }
    43 int pre(int y){
    44     splay(y,root); return querynum(ch[y][0],sz[ch[y][0]]);
    45 }
    46 int nex(int y){
    47     splay(y,root); return querynum(ch[y][1],1);
    48 }
    49 void add(int x,int y,int z){
    50     splay(y,root); splay(x,ch[root][0]); ch[x][1]=z; fa[z]=x; update(x); update(root);
    51 }
    52 void erase(int z){
    53     int x=pre(z),y=nex(z); splay(y,root); splay(x,ch[root][0]); ch[x][1]=0; fa[z]=0; update(x); update(root);
    54 }
    55 void top(int s){
    56     int x=pos[s]; erase(x); int y=querynum(root,1),z=nex(y); add(y,z,x);
    57 }
    58 void bottom(int s){
    59     int x=pos[s]; erase(x); int y=querynum(root,sz[root]-1),z=nex(y); add(y,z,x);
    60 }
    61 void insert(int s,int t){
    62     int a1=pos[s],a2=queryrank(a1)+t; erase(a1); int a3=querynum(root,a2),a4=nex(a3); add(a3,a4,a1);
    63 }
    64 int ask(int s){return queryrank(pos[s])-1;}
    65 int query(int s){return v[querynum(root,s+1)];}
    66 int main(){
    67     n=read(); m=read(); inc(i,2,n+1)book[i]=read(); tot=root=1; build(root,1,n+2);
    68     inc(i,1,m){
    69         char opt[8]; scanf("%s",opt);
    70         if(opt[0]=='T'){int a=read(); top(a);}
    71         if(opt[0]=='B'){int a=read(); bottom(a);}
    72         if(opt[0]=='I'){int a=read(),b=read(); insert(a,b);}
    73         if(opt[0]=='A'){int a=read(); printf("%d
    ",ask(a));}
    74         if(opt[0]=='Q'){int a=read(); printf("%d
    ",query(a));}
    75     }
    76     return 0;
    77 }

    20160811

  • 相关阅读:
    GPS授时服务器(卫星同步时钟)科普小知识
    GPS和北斗卫星授时技术在时频领域的应用和发展
    NTP时间同步服务器(NTP时间服务器)在北京邮电大学的应用案例
    北斗时钟源(GPS网络时钟源)在校园网络应用
    NTP时钟源(GPS时间源)介绍与分析 安徽京准电子科技
    搭建ntp时间服务器并配置集群自动时钟同步
    GPS北斗网络时间源在内网域控制器上的设置方法
    肺炎疫情过后最想干的几件事
    提升苏州城市地位的几个建议
    江苏省如要打造一线城市,很简单!
  • 原文地址:https://www.cnblogs.com/YuanZiming/p/5769472.html
Copyright © 2020-2023  润新知