• BZOJ 1901 Dynamic Rankings


    题面:

    1901: Zju2112 Dynamic Rankings

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 8088  Solved: 3364
    [Submit][Status][Discuss]

    Description

    给定一个含有n个数的序列a[1],a[2],a[3]……a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i],a[i+1
    ],a[i+2]……a[j]中第k小的数是多少(1≤k≤j-i+1),并且,你可以改变一些a[i]的值,改变后,程序还能针对改
    变后的a继续回答上面的问题。

    Input

    第一行一个数字N,代表测试组数
    对于每组数据第一行有两个正整数n(1≤n≤10000),m(1≤m≤10000)。
    分别表示序列的长度和指令的个数。
    第二行有n个数,表示a[1],a[2]……a[n],这些数都小于10^9。
    接下来的m行描述每条指令
    每行的格式是下面两种格式中的一种。 
    Q i j k 或者 C i t 
    Q i j k (i,j,k是数字,1≤i≤j≤n, 1≤k≤j-i+1)
    表示询问指令,询问a[i],a[i+1]……a[j]中第k小的数。
    C i t (1≤i≤n,0≤t≤10^9)表示把a[i]改变成为t

    Output

     对于每一次询问,你都需要输出他的答案,每一个输出占单独的一行。

    Sample Input

    1
    5 3
    3 2 1 4 7
    Q 1 4 3
    C 2 6
    Q 2 5 3

    Sample Output

    3
    6

    HINT

    m,n≤10000。

    Source

    题意:带修改区间k小值,线段树+splay。

      1 #include<stdio.h>
      2 using namespace std;
      3 #define maxn 500001
      4 #define lson id<<1,l,mid
      5 #define rson id<<1|1,mid+1,r
      6 int s[50001];
      7 int n,m;
      8 struct node
      9 {
     10     int w,size,count;
     11     node *fa,*son[2];
     12 }tree[maxn<<2],*stk[maxn<<2];
     13 int top,indx;
     14 class Splay
     15 {
     16     private:
     17         node *newnode(int w,node *f)
     18         {
     19             node *t;
     20             if(top)t=stk[--top];
     21             else t=&tree[indx++];
     22             t->w=w;t->size=t->count=1;
     23             t->fa=f;t->son[0]=t->son[1]=NULL;
     24             return t;
     25         }
     26         inline void freenode(node *t)
     27         {
     28             stk[top++]=t;
     29         }
     30         inline int size(node *t)
     31         {
     32             return t==NULL?0:t->size;
     33         }
     34         inline bool Son(node *f,node *t)
     35         {
     36             return f==NULL?0:f->son[1]==t;
     37         }
     38         inline void update(node *t)
     39         {
     40             if(t==NULL)return ;
     41             t->size=t->count+size(t->son[0])+size(t->son[1]);
     42         }
     43         inline void connect(node *f,node *t,bool flag)
     44         {
     45             if(f==NULL)root=t;
     46             else f->son[flag]=t;
     47             if(t!=NULL)t->fa=f;
     48         }
     49         void rotate(node *t)
     50         {
     51             node *f=t->fa;node *g=f->fa;
     52             bool a=Son(f,t),b=!a;
     53             connect(f,t->son[b],a);
     54             connect(t,f,b);
     55             connect(g,t,Son(g,f));
     56             update(f);update(t);
     57         }
     58         void splay(node *t,node *p)
     59         {
     60             if(t==NULL)return ;
     61             node *f,*g;
     62             while(t->fa!=p)
     63             {
     64                 f=t->fa;g=f->fa;
     65                 if(g==p)rotate(t);
     66                 else
     67                 if(Son(f,t)^Son(g,f))rotate(t),rotate(t);
     68                 else rotate(f),rotate(t);
     69             }
     70         }
     71         node *find(int w)
     72         {
     73             node *t=root;
     74             while(t!=NULL&&t->w!=w)
     75                 t=t->son[w>=t->w];
     76             return splay(t,NULL),t;
     77         }
     78         node *insert(node *t,int w)
     79         {
     80             node *p=t->son[w>=t->w];
     81             if(p==NULL) 
     82                 p=t->son[w>=t->w]=newnode(w,t);
     83             else
     84                 p=insert(p,w);
     85             return update(t),p;
     86         }
     87         void erase(node *t)
     88         {
     89             if(t->son[0]==NULL)
     90             {
     91                 connect(NULL,t->son[1],0);
     92                 update(root);
     93             }
     94             else
     95                 if(t->son[1]==NULL)
     96                 {
     97                     connect(NULL,t->son[0],0);
     98                     update(root);
     99                 }
    100                 else   
    101                 {
    102                     node *p=t->son[0];
    103                     while(p->son[1]!=NULL)   
    104                         p=p->son[1];
    105                     splay(p,t);
    106                     connect(NULL,p,0);
    107                     connect(p,t->son[1],1);
    108                     update(root);
    109                 }
    110             freenode(t);
    111         }
    112         void erase(node *t,int k)
    113         {
    114             t->count-=k;
    115             if(t->count<=0)
    116                 erase(t);
    117             else
    118                 update(t);
    119         }
    120     public:
    121         int l,r;
    122         node *root;
    123         Splay()
    124         {
    125             root=NULL;
    126         }
    127         void insert(int w)
    128         {
    129             if(find(w)!=NULL)
    130                 ++root->count,update(root);
    131             else
    132                 if(root==NULL)  
    133                     root=newnode(w,NULL);
    134                 else
    135                     splay(insert(root,w),NULL);
    136         }
    137         void erase(int w)
    138         {
    139             if(find(w)!=NULL)   
    140                 erase(root,1);
    141         }
    142         int RANK(node *t,int w)
    143         {
    144             if(t==NULL)
    145                 return 0;
    146             if(t->w==w)
    147                 return size(t->son[0]);
    148             if(t->w>w)
    149                 return RANK(t->son[0],w);
    150             return size(t->son[0])+t->count+RANK(t->son[1],w); 
    151         }
    152         void clear()
    153         {
    154             root=NULL;
    155         }
    156 }a[maxn<<2];
    157 int cnt,xx;
    158 void clear()
    159 {
    160     for(int i=1;i<=cnt;i++)
    161         a[i].clear();
    162     cnt=0;
    163 }
    164 void build(int id,int l,int r)
    165 {
    166     ++cnt;
    167     a[id].l=l;a[id].r=r;
    168     for(int i=l;i<=r;i++)    
    169         a[id].insert(s[i]);
    170     if(l==r)
    171         return ;
    172     int mid=(l+r)>>1;
    173     build(lson);
    174     build(rson);
    175 }
    176 void change(int id,int p,int w)
    177 {
    178     a[id].erase(s[p]);
    179     a[id].insert(w);
    180     if(a[id].l==a[id].r)
    181         return ;
    182     int mid=(a[id].l+a[id].r)>>1;
    183     if(p<=mid)   
    184         change(id<<1,p,w);
    185     else
    186         change(id<<1|1,p,w);
    187 }
    188 int query(int id,int l,int r,int w)
    189 {
    190     if(l<=a[id].l&&a[id].r<=r)
    191         return a[id].RANK(a[id].root,w);
    192     int mid=(a[id].l+a[id].r)>>1;
    193     if(r<=mid)
    194         return query(id<<1,l,r,w);
    195     else
    196         if(l>mid)
    197             return query(id<<1|1,l,r,w);
    198         else
    199             return query(id<<1,l,mid,w)+query(id<<1|1,mid+1,r,w);
    200 }
    201 int QUEST(int l,int r,int k)
    202 {
    203     int L=0,R=1e9,mid,ans,x;
    204     while(L<=R)
    205     {
    206         mid=L+R>>1;
    207         x=query(1,l,r,mid);
    208         if(x<=k-1)
    209             L=mid+1,ans=mid;
    210         else
    211             R=mid-1;
    212     }
    213     return ans;
    214 }
    215 int main()
    216 {
    217     char ss[11];
    218     int x,y,z,T;
    219     scanf("%d%d",&n,&m);
    220     for(int i=1;i<=n;i++)
    221         scanf("%d",&s[i]);
    222     build(1,1,n);
    223     for(int i=1;i<=m;i++)
    224     {
    225         scanf("%s",ss);
    226         if(ss[0]=='Q')
    227         {
    228             scanf("%d%d%d",&x,&y,&z);
    229             printf("%d
    ",QUEST(x,y,z));
    230         }
    231         else
    232         {
    233             scanf("%d%d",&x,&y);
    234             change(1,x,y);
    235             s[x]=y;
    236         }
    237     }
    238 }
    BZOJ 1901
  • 相关阅读:
    snabbdom源码(二)
    linux汇总 文本操作三篇之grep
    snabbdom源码(一)
    linux汇总 文本操作三篇之sed
    你的c语言中文版项目使用 char 还是 wchar_t?
    实习经验谈
    fastdfs 安装和使用
    redison 自动续期的 分布式锁
    vue3 中的axios的使用,使用Vue.prototype 报错问题
    vue3的 keepalive 使用,以及activated钩子 和 vuerouter中的 scrollBehavior的使用
  • 原文地址:https://www.cnblogs.com/radioteletscope/p/7270812.html
Copyright © 2020-2023  润新知