zoukankan      html  css  js  c++  java
  • bzoj3196: Tyvj 1730 二逼平衡树 树套树

    地址:http://www.lydsy.com/JudgeOnline/problem.php?id=3196

    题目:

    3196: Tyvj 1730 二逼平衡树

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 4320  Solved: 1662
    [Submit][Status][Discuss]

    Description

    您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:
    1.查询k在区间内的排名
    2.查询区间内排名为k的值
    3.修改某一位值上的数值
    4.查询k在区间内的前驱(前驱定义为小于x,且最大的数)
    5.查询k在区间内的后继(后继定义为大于x,且最小的数)

    Input

    第一行两个数 n,m 表示长度为n的有序序列和m个操作
    第二行有n个数,表示有序序列
    下面有m行,opt表示操作标号
    若opt=1 则为操作1,之后有三个数l,r,k 表示查询k在区间[l,r]的排名
    若opt=2 则为操作2,之后有三个数l,r,k 表示查询区间[l,r]内排名为k的数
    若opt=3 则为操作3,之后有两个数pos,k 表示将pos位置的数修改为k
    若opt=4 则为操作4,之后有三个数l,r,k 表示查询区间[l,r]内k的前驱
    若opt=5 则为操作5,之后有三个数l,r,k 表示查询区间[l,r]内k的后继

    Output

    对于操作1,2,4,5各输出一行,表示查询结果

    Sample Input

    9 6
    4 2 2 1 9 4 0 1 1
    2 1 4 3
    3 4 10
    2 1 4 3
    1 2 5 9
    4 3 9 5
    5 2 8 5

    Sample Output

    2
    4
    3
    4
    9

    HINT

    1.n和m的数据范围:n,m<=50000


    2.序列中每个数的数据范围:[0,1e8]


    3.虽然原题没有,但事实上5操作的k可能为负数
     
    思路:
      第一次写树套树,以前一直觉得树套树是很可怕的东西,写了后发现思想很简单
      就是。。。。代码好长!debug麻烦!
      写了两小时,debug三小时。。
      不过1A了,美滋滋!
      代码跑了快九秒,好气哦,一定是姿势不对
      1 /**************************************************************
      2     Problem: 3196
      3     User: weeping
      4     Language: C++
      5     Result: Accepted
      6     Time:8668 ms
      7     Memory:83520 kb
      8 ****************************************************************/
      9  
     10 #include <bits/stdc++.h>
     11  
     12 using namespace std;
     13  
     14 #define lc ch[x][0]
     15 #define rc ch[x][1]
     16 #define pr fa[x]
     17  
     18 inline int read()
     19 {
     20     int a=0,f=1; char c=getchar();
     21     while (c<'0'||c>'9') {if (c=='-') f=-1; c=getchar();}
     22     while (c>='0'&&c<='9') {a=a*10+c-'0'; c=getchar();}
     23     return a*f;
     24 }
     25  
     26 const int N = 5e4+7;
     27 const int M = 3e6;
     28  
     29 int n, m, ans, val[N];
     30 int tot, rt[M], ch[M][2], fa[M], key[M], sz[M], cnt[M];
     31  
     32 inline int wh(int x) { return ch[pr][1] == x;}
     33  
     34 inline void init(int x,int ls,int ky)
     35 {
     36     lc=rc=0,sz[x]=cnt[x]=1,key[x]=ky,pr=ls;
     37 }
     38 inline void push_up(int x)
     39 {
     40     sz[x]=sz[lc]+sz[rc]+cnt[x];
     41 }
     42 void rotate(int x)
     43 {
     44     int f = fa[x], gf = fa[f], t1 = wh(x);
     45     if( gf ) ch[gf][wh(f)] = x;
     46     fa[x] = gf, ch[f][t1] = ch[x][1^t1], fa[ch[f][t1]] = f;
     47     ch[x][t1^1] = f, fa[f] = x;
     48     push_up( f ), push_up( x );
     49 }
     50 void splay(int o,int x,int tar)
     51 {
     52     for(;pr!=tar;rotate(x))
     53     if(fa[pr]!=tar)   rotate(wh(x)==wh(pr)?pr:x);
     54     if(!tar)    rt[o]=x;
     55 }
     56 //void debug(int x)
     57 //{
     58 //    if(!x) return;
     59 //    if(lc) debug(lc);
     60 //    for(int i=1;i<=cnt[x];i++)
     61 //        printf("%d ",key[x]);
     62 //    if(rc) debug(rc);
     63 //}
     64 void insert(int o,int ky)
     65 {
     66     int x=rt[o],ls=rt[o];
     67     while(x)
     68     {
     69         if(key[x]==ky)
     70         {
     71             sz[x]++,cnt[x]++,splay(o,x,0);return;
     72         }
     73         ls=x,x=ch[x][ky>key[x]];
     74     }
     75     init(++tot,ls,ky);
     76     if(!rt[o]) { rt[o]=tot; return ;}
     77     x=ls, ch[x][ky>key[x]]=tot;
     78     splay(o,tot,0);
     79 }
     80 int find(int o,int ky)
     81 {
     82     int x=rt[o];
     83     //debug(rt[o]);printf("
    ");
     84     while(x)
     85     {
     86         if(key[x]==ky)  break;
     87         x=ch[x][ky>key[x]];
     88     }
     89     if(x)   splay(o,x,0);
     90     else x=-1;
     91     return x;
     92 }
     93 void merge(int o,int x,int y)
     94 {
     95     if(!x){rt[o]=y;return;}
     96     if(!y)  {rt[o]=x;return;}
     97     while(rc)   x=rc;
     98     splay(o,x,0);
     99     rc=y,fa[y]=x;
    100     push_up(x);
    101 }
    102 void del(int o,int ky)
    103 {
    104     if(!rt[o]) return;
    105     int x=find(o,ky);
    106     if(cnt[x]>1)    {cnt[x]--,sz[x]--;return;}
    107     int tl=lc,tr=rc;
    108     fa[tl]=fa[tr]=cnt[x]=sz[x]=lc=rc=0;
    109     if(sz[x]==1)    {rt[o]=0;return;}
    110     merge(o,tl,tr);
    111 }
    112 void getpre(int x,int ky)
    113 {
    114     if(!x)return;
    115     if(key[x]<ky)  ans=max(ans,key[x]),getpre(rc,ky);
    116     else getpre(lc,ky);
    117 }
    118 void getnext(int x,int ky)
    119 {
    120     if(!x) return;
    121     if(key[x]>ky) ans=min(ans,key[x]),getnext(lc,ky);
    122     else getnext(rc,ky);
    123 }
    124 int getsz(int o,int ky)
    125 {
    126     int x=rt[o],ret=0;
    127     while(x)
    128     {
    129         if(key[x]==ky)  return ret+sz[lc];
    130         if(key[x]<ky)   ret+=sz[lc]+cnt[x],x=rc;
    131         else    x=lc;
    132     }
    133     return ret;
    134 }
    135  
    136 void update(int o,int l,int r,int pos,int x,int op=0)
    137 {
    138     if(op)  del(o,val[pos]);
    139     insert(o,x);
    140     //debug(rt[o]);printf("
    ");
    141     if(l==r) return ;
    142     int mid=l+r>>1;
    143     if(pos<=mid)    update(o<<1,l,mid,pos,x,op);
    144     else    update(o<<1|1,mid+1,r,pos,x,op);
    145 }
    146 int get_rank(int o,int l,int r,int nl,int nr,int ky)
    147 {
    148     //debug(rt[o]);printf("
    ");
    149     if(nl==l&&r==nr)    return getsz(o,ky);
    150     int mid=l+r>>1;
    151     if(nr<=mid) return get_rank(o<<1,l,mid,nl,nr,ky);
    152     else if(nl>mid) return get_rank(o<<1|1,mid+1,r,nl,nr,ky);
    153     return get_rank(o<<1,l,mid,nl,mid,ky)+get_rank(o<<1|1,mid+1,r,mid+1,nr,ky);
    154 }
    155 void get_pre(int o,int l,int r,int nl,int nr,int ky)
    156 {
    157     if(nl==l&&r==nr)    return getpre(rt[o],ky);
    158     int mid=l+r>>1;
    159     if(nr<=mid) return get_pre(o<<1,l,mid,nl,nr,ky);
    160     else if(nl>mid) return get_pre(o<<1|1,mid+1,r,nl,nr,ky);
    161     get_pre(o<<1,l,mid,nl,mid,ky),get_pre(o<<1|1,mid+1,r,mid+1,nr,ky);
    162 }
    163 void get_next(int o,int l,int r,int nl,int nr,int ky)
    164 {
    165     //debug(rt[o]);printf("
    ");
    166     if(nl==l&&r==nr)    return getnext(rt[o],ky);
    167     int mid=l+r>>1;
    168     if(nr<=mid) return get_next(o<<1,l,mid,nl,nr,ky);
    169     else if(nl>mid) return get_next(o<<1|1,mid+1,r,nl,nr,ky);
    170     get_next(o<<1,l,mid,nl,mid,ky),get_next(o<<1|1,mid+1,r,mid+1,nr,ky);
    171 }
    172 int get_kth(int nl,int nr,int k)
    173 {
    174     int l=0,r=1e8+1,ans=0;
    175     while(l<=r)
    176     {
    177         int mid=l+r>>1;
    178         if(get_rank(1,1,n,nl,nr,mid)+1<=k)  l=mid+1,ans=mid;
    179         else    r=mid-1;
    180     }
    181     return ans;
    182 }
    183 int main(void)
    184 {
    185     n=read(),m=read();
    186     for(int i=1;i<=n;i++)
    187         val[i]=read(),update(1,1,n,i,val[i]);
    188     int op,l,r,x;
    189     while(m--)
    190     {
    191         op=read(),l=read(),r=read();
    192         if(op==3)
    193             {update(1,1,n,l,r,1);val[l]=r;continue;}
    194         x=read();
    195         if(op==1)
    196             ans=get_rank(1,1,n,l,r,x)+1;
    197         else if(op==2)
    198             ans=get_kth(l,r,x);
    199         else if(op==4)
    200             ans=-0x3f3f3f3f,get_pre(1,1,n,l,r,x);
    201         else
    202             ans=0x3f3f3f3f,get_next(1,1,n,l,r,x);
    203         printf("%d
    ",ans);
    204     }
    205 }
  • 相关阅读:
    Billing Invoice Split Rule
    From ProjectMagazine
    Link to PMP
    测试发现数据库性能问题后的SQL调优
    被jQuery折腾得半死,揭秘为何jQuery为何在IE/Firefox下均无法使用
    解决'将 expression 转换为数据类型 nvarchar 时出现算术溢出错误。'
    几年来ASP.NET官方站点首次改版,意味着MVC时代全面到来?
    Collection was modified; enumeration operation may not execute.的异常处理
    解决Sandcastle Help File Builder报错问题
    如何查看Windows服务所对应的端口?
  • 原文地址:https://www.cnblogs.com/weeping/p/7668168.html
Copyright © 2011-2022 走看看