• codevs1743


    http://codevs.cn/problem/1743/

    splay区间翻转。

    数字在原序列中的位置保存在splay的data[]中。splay中点的编号为原序列的数字大小。

    每次pushdown只在find时进行就行,因为find结束时splay只会改动i点祖先的信息,而其余时候没有splay操作了。

    记得加个+INF 一个-INF。

      1 #include<cstdio>
      2 #include<algorithm>
      3 using namespace std;
      4 #define N 400000
      5 #define INF 2000000000
      6 int lazy[N],s[N][3],f[N],cnt[N],data[N],root,total;//son:1left 2right 
      7 int fi,num,p,q,le[N],m,n,i,j,ans;
      8 char opt;
      9 struct lbz
     10 {
     11     int a,b;
     12 }x[N];
     13 bool cmp(lbz a,lbz b)
     14 {
     15     return a.a<b.a;
     16 }
     17 void rotate(int x,int w)//w:1leftZag 2rightZig
     18 {
     19     int y;
     20     y=f[x];
     21     cnt[y]=cnt[y]-cnt[x]+cnt[s[x][w]];
     22     cnt[x]=cnt[x]-cnt[s[x][w]]+cnt[y];
     23     s[y][3-w]=s[x][w];
     24     if (s[x][w]!=0)
     25         f[s[x][w]]=y;
     26     f[x]=f[y];
     27     if (f[y]!=0)
     28         if (y==s[f[y]][1])
     29             s[f[y]][1]=x;
     30         else
     31             s[f[y]][2]=x;
     32     f[y]=x;
     33     s[x][w]=y;
     34 }
     35 void splay(int x,int t)
     36 {
     37     int y;
     38     while (f[x]!=t)
     39     {
     40         y=f[x];
     41         if (f[y]==t)
     42             if (x==s[y][1]) 
     43                 rotate(x,2);
     44             else
     45                 rotate(x,1);
     46         else
     47             if (y==s[f[y]][1])
     48                 if (x==s[y][1])
     49                 {
     50                     rotate(y,2);
     51                     rotate(x,2);
     52                 }
     53                 else
     54                 {
     55                     rotate(x,1);
     56                     rotate(x,2);
     57                 }
     58             else
     59                 if (x==s[y][2])
     60                 {
     61                     rotate(y,1);
     62                     rotate(x,1);
     63                 }
     64                 else
     65                 {
     66                     rotate(x,2);
     67                     rotate(x,1);
     68                 }
     69     }
     70     if (f[x]==0) root=x;
     71 }
     72 
     73 int sea(int x,int w)
     74 {
     75     int t;
     76     t=x;
     77     while (1)
     78     {
     79         if (data[t]==w) break;
     80         if (w<=data[t])
     81         {
     82             if (s[t][1]==0) break;
     83             t=s[t][1];
     84         }
     85         else
     86         {
     87             if (s[t][2]==0) break;
     88             t=s[t][2];
     89         }
     90         
     91     }
     92     splay(t,0);
     93     return t;
     94 }
     95 void add(int w)
     96 {
     97     int x;
     98     if (total==0)
     99     {
    100         total++;
    101         f[1]=0;cnt[1]=1;data[1]=w;root=1;
    102         return;
    103     }
    104     x=root;
    105     while(1)
    106     {
    107         cnt[x]++;
    108         if (w<=data[x])
    109         {
    110             if (s[x][1]==0)    break;
    111             x=s[x][1];
    112         }
    113         else
    114         {
    115             if (s[x][2]==0)    break;
    116             x=s[x][2]; 
    117         }
    118     }
    119     total++;
    120     data[total]=w;
    121     f[total]=x;
    122     cnt[total]=1;
    123     if (w<=data[x])
    124         s[x][1]=total;
    125     else
    126         s[x][2]=total;
    127     splay(total,0);    
    128 }
    129 
    130 void pushdown(int x)
    131 {
    132     lazy[x]^=1;
    133     lazy[s[x][1]]^=1;
    134     lazy[s[x][2]]^=1;
    135     swap(s[x][1],s[x][2]);
    136 }
    137 int find(int k,int w)//w=1 Kthsmall;w=2 Kthbig
    138 {
    139     int i,t;
    140     i=root;t=k;
    141     if (lazy[i]==1)
    142         pushdown(i);
    143     
    144     while (t!=cnt[s[i][w]]+1)
    145     {
    146 
    147         if (t>cnt[s[i][w]]+1)
    148         {
    149             t-=cnt[s[i][w]]+1;
    150             i=s[i][3-w];
    151         }
    152         else
    153             i=s[i][w];    
    154         if (lazy[i]==1)
    155             pushdown(i);
    156     }
    157     splay(i,0);
    158     return i;
    159 }
    160 
    161 int rec(int l,int r)
    162 {
    163     int ll,rr;
    164     ll=find(l,1);
    165     rr=find(r+2,1);
    166     splay(ll,0);
    167     splay(rr,ll);
    168     lazy[s[rr][1]]^=1;
    169 }
    170 int main()
    171 {
    172     scanf("%d",&n);
    173     for (i=1;i<=n;i++)
    174     {
    175         scanf("%d",&x[i].a);
    176         x[i].b=i;
    177     }
    178     sort(x+1,x+1+n,cmp);
    179     for (i=1;i<=n;i++)
    180         add(x[i].b);
    181     add(1000000000);
    182     add(-1000000000);
    183     while (1)
    184     {
    185         fi=find(2,1);
    186         if (fi==1) break;
    187         rec(1,fi);
    188         ans++;
    189     }
    190     printf("%d
    ",ans);
    191     return 0;        
    192 }
    View Code
    ------------------------------------------------------------------------- 花有重开日,人无再少年
  • 相关阅读:
    Android 视图切换库的使用
    Ext3.4--TreeGridDemo
    Extjs不错的博客
    Extjs学习笔记--(六,选择器)
    Webservice简单案例
    Extjs学习笔记--(五,事件)
    Extjs学习笔记--(四,基本函数介绍)
    Extjs学习笔记--(三,调试技巧)
    SQL集合运算:差集、交集、并集
    Extjs学习笔记--(二)
  • 原文地址:https://www.cnblogs.com/lbz007oi/p/5869827.html
Copyright © 2020-2023  润新知