• [BZOJ1901]Dynamic Rankings


    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(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
    m,n≤10000

    Output

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

    Sample Input

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

    Sample Output

    3
    6
     
    第一次写树状数组套主席树,还是很好写的,思路也非常好理解
    代码:
     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #define M 20010
     6 #define ls L[node]
     7 #define rs R[node]
     8 using namespace std;
     9 int n,m,sz,cnt,tx,ty;
    10 int a[M<<3],b[M<<3],px[M<<3],py[M<<3],ql[M<<3],qr[M<<3],qk[M<<3];
    11 int rt[M<<3],val[M<<9],L[M<<9],R[M<<9];
    12 void insert(int &node,int l,int r,int x,int v) {
    13     if(!node) node=++sz;val[node]+=v;
    14     if(l==r) return;
    15     int mid=(l+r)/2;
    16     if(x<=mid) insert(ls,l,mid,x,v);
    17     else insert(rs,mid+1,r,x,v);
    18 }
    19 void add(int loc,int v) {
    20     int p=lower_bound(b+1,b+1+cnt,a[loc])-b;
    21     for(int i=loc;i<=n;i+=(i&-i))
    22         insert(rt[i],1,cnt,p,v);
    23 }
    24 int query(int l,int r,int k) {
    25     if(l==r) return l;
    26     int sum=0,mid=(l+r)/2;
    27     for(int i=1;i<=tx;i++) sum-=val[L[px[i]]];
    28     for(int i=1;i<=ty;i++) sum+=val[L[py[i]]];
    29     if(k<=sum) {
    30         for(int i=1;i<=tx;i++) px[i]=L[px[i]];
    31         for(int i=1;i<=ty;i++) py[i]=L[py[i]];
    32         return query(l,mid,k);
    33     }
    34     else {
    35         k-=sum;
    36         for(int i=1;i<=tx;i++) px[i]=R[px[i]];
    37         for(int i=1;i<=ty;i++) py[i]=R[py[i]];
    38         return query(mid+1,r,k);
    39     }
    40 }
    41 int main() {
    42     scanf("%d%d",&n,&m);cnt=n;
    43     for(int i=1;i<=n;i++) scanf("%d",&a[i]),b[i]=a[i];
    44     for(int i=1;i<=m;i++) {
    45         char s[10];scanf("%s",s);
    46         scanf("%d%d",&ql[i],&qr[i]);
    47         if(s[0]=='Q') scanf("%d",&qk[i]);
    48         else b[++cnt]=qr[i];
    49     }
    50     sort(b+1,b+1+cnt);
    51     cnt=unique(b+1,b+1+cnt)-b-1;
    52     for(int i=1;i<=n;i++) add(i,1);
    53     for(int i=1;i<=m;i++) {
    54         if(qk[i]) {
    55             tx=ty=0;
    56             for(int j=ql[i]-1;j;j-=(j&-j)) px[++tx]=rt[j];
    57             for(int j=qr[i];j;j-=(j&-j)) py[++ty]=rt[j];
    58             printf("%d
    ",b[query(1,cnt,qk[i])]);
    59         }
    60         else {
    61             add(ql[i],-1);
    62             a[ql[i]]=qr[i];
    63             add(ql[i],1);
    64         }
    65     }
    66     return 0;
    67 }
  • 相关阅读:
    silverlight 调用默认打印机
    拿来主意
    关于js智能提示的封装(修订版)
    silverlight 获取文本框焦点
    silverlight Timer
    winform 中写app.config文件时 调试情况下没有改变的原因
    关于asp:GridView和dx:ASPxGridView固定表头的jquery代码封装
    Microsoft Visual Studio 2010的前世今生
    游戏开发之我见
    JS中数组去重
  • 原文地址:https://www.cnblogs.com/Slrslr/p/10056659.html
Copyright © 2020-2023  润新知