• bzoj 3223 文艺平衡树 splay 区间翻转


    Tyvj 1728 普通平衡树

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 17715  Solved: 7769
    [Submit][Status][Discuss]

    Description

    您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:
    1. 插入x数
    2. 删除x数(若有多个相同的数,因只删除一个)
    3. 查询x数的排名(若有多个相同的数,因输出最小的排名)
    4. 查询排名为x的数
    5. 求x的前驱(前驱定义为小于x,且最大的数)
    6. 求x的后继(后继定义为大于x,且最小的数)

    Input

    第一行为n,表示操作的个数,下面n行每行有两个数opt和x,opt表示操作的序号(1<=opt<=6)

    Output

    对于操作3,4,5,6每行输出一个数,表示对应答案

    Sample Input

    10
    1 106465
    4 1
    1 317721
    1 460929
    1 644985
    1 84185
    1 89851
    6 81968
    1 492737
    5 493598

    Sample Output

    106465
    84185
    492737

    HINT

    1.n的数据范围:n<=100000

    2.每个数的数据范围:[-2e9,2e9]

    Source

     
    题解:
      区间翻转就没了。
      1 #include<cstring>
      2 #include<cmath>
      3 #include<algorithm>
      4 #include<iostream>
      5 #include<cstdio>
      6 
      7 #define inf 1000000007
      8 #define N 100007
      9 #define ls c[p][0]
     10 #define rs c[p][1]
     11 using namespace std;
     12 inline int read()
     13 {
     14     int x=0,f=1;char ch=getchar();
     15     while(ch>'9'||ch<'0'){if (ch=='-') f=-1;ch=getchar();}
     16     while(ch<='9'&&ch>='0'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
     17     return x*f;
     18 }
     19 
     20 int n,m,rt;
     21 int fa[N],val[N],rev[N],mx[N],sz[N],flag[N],c[N][2];
     22 
     23 inline void update(int p)
     24 {
     25     sz[p]=sz[ls]+sz[rs]+1;
     26 }
     27 inline void pushdown(int p)
     28 {
     29     if (rev[p])
     30     {
     31         rev[p]^=1;
     32         rev[ls]^=1,rev[rs]^=1;
     33         swap(c[p][1],c[p][0]);
     34     }
     35 }
     36 void rotate(int x,int &k)
     37 {
     38     int y=fa[x],z=fa[y],l,r;
     39     if (c[y][0]==x) l=0;else l=1;r=l^1;
     40     if (y==k) k=x;//交换后x就等于y 
     41     else if (c[z][0]==y) c[z][0]=x;
     42     else c[z][1]=x;
     43     fa[x]=z,fa[y]=x,fa[c[x][r]]=y;
     44     c[y][l]=c[x][r],c[x][r]=y;
     45     update(y),update(x);
     46 }
     47 void splay(int x,int &k)
     48 {
     49     while(x!=k)
     50     {
     51         int y=fa[x],z=fa[y];
     52         if (y!=k)
     53         {
     54             if (c[y][0]==x^c[z][0]==y) rotate(x,k);
     55             else rotate(y,k);
     56         }
     57         rotate(x,k);
     58     }
     59 }
     60 int find(int p,int num)
     61 {
     62     pushdown(p);
     63     if (sz[ls]>=num) return find(ls,num);
     64     else if (sz[ls]+1==num) return p;
     65     else return find(rs,num-sz[ls]-1); 
     66 }
     67 void spin(int l,int r)
     68 {
     69     int x=find(rt,l),y=find(rt,r+2);
     70     splay(x,rt),splay(y,c[x][1]);
     71     int now=c[c[x][1]][0];
     72     rev[now]^=1;
     73 }
     74 void build(int l,int r,int p)
     75 {
     76     if (l>r) return;
     77     if (l==r)
     78     {
     79         fa[l]=p,sz[l]=1,val[l]=l;
     80         if (l<p) c[p][0]=l;
     81         else c[p][1]=l;
     82         return;
     83     }
     84     int mid=(l+r)>>1;
     85     build(l,mid-1,mid),build(mid+1,r,mid);
     86     fa[mid]=p,val[mid]=mid;
     87     if (mid<p) c[p][0]=mid;
     88     else c[p][1]=mid;
     89     update(mid);
     90 }
     91 int main()
     92 {    
     93     n=read(),m=read();
     94     build(1,n+2,0),rt=(n+3)>>1;
     95     while(m--)
     96     {
     97         int x=read(),y=read();
     98         spin(x,y);
     99     }
    100     for (int i=1;i<=n;i++)
    101     {
    102         int x=find(rt,i+1);
    103         if (i==1) cout<<val[x]-1;
    104         else cout<<" "<<val[x]-1;
    105     }
    106 }
  • 相关阅读:
    读后感悟
    使用java的循环单向链表解决约瑟夫问题
    稀疏数组
    java实现队列
    ASP.NET学习4. ASP.NET Ajax下POST完成后调用javascript函数
    ASP.NET学习3.前端和后台的相互调用
    ASP.NET学习1.使用“<% %>”嵌入代码
    ASP.NET学习2.弹出对话框的方法
    HTML5程序怎么打包成windows phne, ios和android的应用[转]
    PHP多文件上传个人理解总结 [转]
  • 原文地址:https://www.cnblogs.com/fengzhiyuan/p/8097975.html
Copyright © 2020-2023  润新知