zoukankan      html  css  js  c++  java
  • bzoj 3223: Tyvj 1729 文艺平衡树

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 2853  Solved: 1602
    [Submit][Status][Discuss]

    Description

    您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2 3 4 1 

    Input

    第一行为n,m n表示初始序列有n个数,这个序列依次是(1,2……n-1,n)  m表示翻转操作次数
    接下来m行每行两个数[l,r] 数据保证 1<=l<=r<=n 

    Output

    输出一行n个数字,表示原始序列经过m次变换后的结果 

    Sample Input

    5 3
    1 3
    1 3
    1 4

    Sample Output

    4 3 2 1 5

    HINT

    N,M<=100000

    题解:

      给定一个序列要求区间翻转,可以用splay来维护,只要让左区间的前驱旋到根,右区间的后继选到根的右孩子,那么根的右孩子的左孩子所在子树就是需要翻转的区间,打上标记维护一下就行了。其实可以发现,这并不是严格的平衡树,因为对于x节点,它的左孩子的权值未必比右孩子小。最后只要按照中序遍历输出一下就好了。

      1 /**************************************************************
      2     Problem: 3223
      3     User: __abcdef__
      4     Language: C++
      5     Result: Accepted
      6     Time:3124 ms
      7     Memory:4020 kb
      8 ****************************************************************/
      9  
     10 #include<iostream>
     11 #include<cstdio>
     12 #include<cstdlib>
     13 #include<cstring>
     14 #include<cmath>
     15 #include<algorithm>
     16 #include<queue>
     17 #include<vector>
     18 #include<ctime>
     19 using namespace std;
     20 typedef long long LL;
     21 const int inf=1e9;
     22 const int maxn=100005;
     23 int N,M,tot,root;
     24 int key[maxn],lc[maxn],rc[maxn],fa[maxn],siz[maxn];
     25 int rev[maxn];
     26 int ans[maxn],cnt;
     27 inline void update(int x){
     28     siz[x]=siz[lc[x]]+siz[rc[x]]+1;
     29 }
     30 inline void pushdown(int x){
     31     if(rev[x]){
     32         swap(lc[x],rc[x]);
     33         rev[lc[x]]^=1; rev[rc[x]]^=1;
     34         rev[x]=0;
     35     }
     36 }
     37 inline void r_rotate(int x){
     38     int y=fa[x];
     39     lc[y]=rc[x];
     40     if(rc[x]) fa[rc[x]]=y;
     41     fa[x]=fa[y];
     42     if(y==lc[fa[y]]) lc[fa[y]]=x;
     43     else rc[fa[y]]=x;
     44     fa[y]=x; rc[x]=y;
     45     update(y); update(x); 
     46 }
     47 inline void l_rotate(int x){
     48     int y=fa[x];
     49     rc[y]=lc[x];
     50     if(lc[x]) fa[lc[x]]=y;
     51     fa[x]=fa[y];
     52     if(y==lc[fa[y]]) lc[fa[y]]=x;
     53     else rc[fa[y]]=x;
     54     fa[y]=x;  lc[x]=y;
     55     update(y); update(x);
     56 }
     57 inline void splay(int x,int s){
     58     int p;
     59     while(fa[x]!=s){
     60         int p=fa[x];
     61         if(fa[p]==s){
     62             if(x==lc[p]) r_rotate(x);
     63             else l_rotate(x);
     64             break;
     65         }
     66         else if (x==lc[p]){
     67             if(p==lc[fa[p]]) r_rotate(x),r_rotate(x);
     68             else r_rotate(x),l_rotate(x);
     69         }
     70         else if(x==rc[p]){
     71             if(p==rc[fa[p]]) l_rotate(x),l_rotate(x);
     72             else l_rotate(x),r_rotate(x);
     73         }
     74     }
     75     if(s==0) root=x;
     76 }
     77 inline void insert(int v){
     78     if(root==0){
     79         root=++tot;
     80         rc[0]=tot; key[root]=v; siz[root]=1;
     81         return ;
     82     }
     83     int p,x=root;
     84     while(x!=0){
     85         p=x;
     86         if(v<=key[x]) siz[x]++,x=lc[x];
     87         else siz[x]++,x=rc[x];
     88     }
     89     if(v<=key[p]){
     90         lc[p]=++tot; 
     91         key[tot]=v; fa[tot]=p; siz[tot]=1;
     92     }
     93     else{
     94         rc[p]=++tot;
     95         key[tot]=v; fa[tot]=p; siz[tot]=1;
     96     }
     97     splay(tot,0);
     98 }
     99 inline int findkth(int x,int k){
    100     pushdown(x);
    101     if(siz[lc[x]]+1==k) return x;
    102     else if(siz[lc[x]]+1>k) return findkth(lc[x],k);
    103     else return findkth(rc[x],k-siz[lc[x]]-1);
    104 }
    105 inline void rever(int L,int R){
    106     int x=findkth(root,L),y=findkth(root,R+2);
    107     splay(x,0); 
    108     splay(y,x);
    109     rev[lc[rc[root]]]^=1;
    110 }
    111 inline void print(int x){
    112     pushdown(x);
    113     if(lc[x]!=0) print(lc[x]);
    114     ans[++cnt]=key[x];
    115     if(rc[x]!=0) print(rc[x]);
    116 }
    117 int main(){
    118     scanf("%d%d",&N,&M);
    119     insert(-inf); insert(inf);
    120     for(int i=1;i<=N;i++) insert(i);
    121     while(M--){
    122         int L,R;
    123         scanf("%d%d",&L,&R);
    124         rever(L,R);
    125     }
    126     print(root);
    127     for(int i=2;i<=cnt-1;i++) printf("%d ",ans[i]);
    128     return 0;
    129 }
  • 相关阅读:
    K-means聚类
    支持向量机_原理
    回归+内插
    ftp 服务器
    cmd 切换python版本
    cookie
    类加载器
    GC
    jvm结构
    mysql文件
  • 原文地址:https://www.cnblogs.com/CXCXCXC/p/5361390.html
Copyright © 2011-2022 走看看