zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    Java 第十一届 蓝桥杯 省模拟赛 梅花桩
    Java 第十一届 蓝桥杯 省模拟赛 梅花桩
    Java 第十一届 蓝桥杯 省模拟赛 梅花桩
    Java 第十一届 蓝桥杯 省模拟赛 元音字母辅音字母的数量
    Java 第十一届 蓝桥杯 省模拟赛 元音字母辅音字母的数量
    Java 第十一届 蓝桥杯 省模拟赛 元音字母辅音字母的数量
    Java 第十一届 蓝桥杯 省模拟赛 最大的元素距离
    Java 第十一届 蓝桥杯 省模拟赛 递增序列
    Java 第十一届 蓝桥杯 省模拟赛 递增序列
    Java 第十一届 蓝桥杯 省模拟赛 最大的元素距离
  • 原文地址:https://www.cnblogs.com/YuanZiming/p/5769472.html
Copyright © 2011-2022 走看看