zoukankan      html  css  js  c++  java
  • ZOJ 2112 Dynamic Rankings (动态第k大,树状数组套主席树)

    Dynamic Rankings

    Time Limit: 10 Seconds      Memory Limit: 32768 KB

    The Company Dynamic Rankings has developed a new kind of computer that is no longer satisfied with the query like to simply find the k-th smallest number of the given N numbers. They have developed a more powerful system such that for N numbers a[1], a[2], ..., a[N], you can ask it like: what is the k-th smallest number of a[i], a[i+1], ..., a[j]? (For some i<=j, 0<k<=j+1-i that you have given to it). More powerful, you can even change the value of some a[i], and continue to query, all the same.

    Your task is to write a program for this computer, which

    - Reads N numbers from the input (1 <= N <= 50,000)

    - Processes M instructions of the input (1 <= M <= 10,000). These instructions include querying the k-th smallest number of a[i], a[i+1], ..., a[j] and change some a[i] to t.


    Input

    The first line of the input is a single number X (0 < X <= 4), the number of the test cases of the input. Then X blocks each represent a single test case.

    The first line of each block contains two integers N and M, representing N numbers and M instruction. It is followed by N lines. The (i+1)-th line represents the number a[i]. Then M lines that is in the following format

    Q i j k or
    C i t

    It represents to query the k-th number of a[i], a[i+1], ..., a[j] and change some a[i] to t, respectively. It is guaranteed that at any time of the operation. Any number a[i] is a non-negative integer that is less than 1,000,000,000.

    There're NO breakline between two continuous test cases.


    Output

    For each querying operation, output one integer to represent the result. (i.e. the k-th smallest number of a[i], a[i+1],..., a[j])

    There're NO breakline between two continuous test cases.


    Sample Input

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


    Sample Output

    3
    6
    3
    6

    主席树太神了。

    这题是动态第k大。

    如果是不修改,直接主席树就可以了。

    要修改要套如树状数组求和。

    参考链接:

    http://blog.csdn.net/acm_cxlove/article/details/8565309

    http://www.cnblogs.com/Rlemon/archive/2013/05/24/3096264.html

    http://seter.is-programmer.com/posts/31907.html

    http://blog.csdn.net/metalseed/article/details/8045038

      1 /* ***********************************************
      2 Author        :kuangbin
      3 Created Time  :2013-9-8 8:53:54
      4 File Name     :F:2013ACM练习专题学习主席树OJ2112.cpp
      5 ************************************************ */
      6 
      7 #include <stdio.h>
      8 #include <string.h>
      9 #include <iostream>
     10 #include <algorithm>
     11 #include <vector>
     12 #include <queue>
     13 #include <set>
     14 #include <map>
     15 #include <string>
     16 #include <math.h>
     17 #include <stdlib.h>
     18 #include <time.h>
     19 using namespace std;
     20 
     21 const int MAXN = 60010;
     22 const int M = 2500010;
     23 int n,q,m,tot;
     24 int a[MAXN], t[MAXN];
     25 int T[MAXN], lson[M], rson[M],c[M];
     26 int S[MAXN];
     27 
     28 struct Query
     29 {
     30     int kind;
     31     int l,r,k;
     32 }query[10010];
     33 
     34 void Init_hash(int k)
     35 {
     36     sort(t,t+k);
     37     m = unique(t,t+k) - t;
     38 }
     39 int hash(int x)
     40 {
     41     return lower_bound(t,t+m,x)-t;
     42 }
     43 int build(int l,int r)
     44 {
     45     int root = tot++;
     46     c[root] = 0;
     47     if(l != r)
     48     {
     49         int mid = (l+r)/2;
     50         lson[root] = build(l,mid);
     51         rson[root] = build(mid+1,r);
     52     }
     53     return root;
     54 }
     55 
     56 int Insert(int root,int pos,int val)
     57 {
     58     int newroot = tot++, tmp = newroot;
     59     int l = 0, r = m-1;
     60     c[newroot] = c[root] + val;
     61     while(l < r)
     62     {
     63         int mid = (l+r)>>1;
     64         if(pos <= mid)
     65         {
     66             lson[newroot] = tot++; rson[newroot] = rson[root];
     67             newroot = lson[newroot]; root = lson[root];
     68             r = mid;
     69         }
     70         else
     71         {
     72             rson[newroot] = tot++; lson[newroot] = lson[root];
     73             newroot = rson[newroot]; root = rson[root];
     74             l = mid+1;
     75         }
     76         c[newroot] = c[root] + val;
     77     }
     78     return tmp;
     79 }
     80 
     81 int lowbit(int x)
     82 {
     83     return x&(-x);
     84 }
     85 int use[MAXN];
     86 void add(int x,int pos,int val)
     87 {
     88     while(x <= n)
     89     {
     90         S[x] = Insert(S[x],pos,val);
     91         x += lowbit(x);
     92     }
     93 }
     94 int sum(int x)
     95 {
     96     int ret = 0;
     97     while(x > 0)
     98     {
     99         ret += c[lson[use[x]]];
    100         x -= lowbit(x);
    101     }
    102     return ret;
    103 }
    104 int Query(int left,int right,int k)
    105 {
    106     int left_root = T[left-1];
    107     int right_root = T[right];
    108     int l = 0, r = m-1;
    109     for(int i = left-1;i;i -= lowbit(i)) use[i] = S[i];
    110     for(int i = right;i ;i -= lowbit(i)) use[i] = S[i];
    111     while(l < r)
    112     {
    113         int mid = (l+r)/2;
    114         int tmp = sum(right) - sum(left-1) + c[lson[right_root]] - c[lson[left_root]];
    115         if(tmp >= k)
    116         {
    117             r = mid;
    118             for(int i = left-1; i ;i -= lowbit(i))
    119                 use[i] = lson[use[i]];
    120             for(int i = right; i; i -= lowbit(i))
    121                 use[i] = lson[use[i]];
    122             left_root = lson[left_root];
    123             right_root = lson[right_root];
    124         }
    125         else
    126         {
    127             l = mid+1;
    128             k -= tmp;
    129             for(int i = left-1; i;i -= lowbit(i))
    130                 use[i] = rson[use[i]];
    131             for(int i = right;i ;i -= lowbit(i))
    132                 use[i] = rson[use[i]];
    133             left_root = rson[left_root];
    134             right_root = rson[right_root];
    135         }
    136     }
    137     return l;
    138 }
    139 void Modify(int x,int p,int d)
    140 {
    141     while(x <= n)
    142     {
    143         S[x] = Insert(S[x],p,d);
    144         x += lowbit(x);
    145     }
    146 }
    147 
    148 int main()
    149 {
    150     //freopen("in.txt","r",stdin);
    151     //freopen("out.txt","w",stdout);
    152     int Tcase;
    153     scanf("%d",&Tcase);
    154     while(Tcase--)
    155     {
    156         scanf("%d%d",&n,&q);
    157         tot = 0;
    158         m = 0;
    159         for(int i = 1;i <= n;i++)
    160         {
    161             scanf("%d",&a[i]);
    162             t[m++] = a[i];
    163         }
    164         char op[10];
    165         for(int i = 0;i < q;i++)
    166         {
    167             scanf("%s",op);
    168             if(op[0] == 'Q')
    169             {
    170                 query[i].kind = 0;
    171                 scanf("%d%d%d",&query[i].l,&query[i].r,&query[i].k);
    172             }
    173             else
    174             {
    175                 query[i].kind = 1;
    176                 scanf("%d%d",&query[i].l,&query[i].r);
    177                 t[m++] = query[i].r;
    178             }
    179         }
    180         Init_hash(m);
    181         T[0] = build(0,m-1);
    182         for(int i = 1;i <= n;i++)
    183             T[i] = Insert(T[i-1],hash(a[i]),1);
    184         for(int i = 1;i <= n;i++)
    185             S[i] = T[0];
    186         for(int i = 0;i < q;i++)
    187         {
    188             if(query[i].kind == 0)
    189                 printf("%d
    ",t[Query(query[i].l,query[i].r,query[i].k)]);
    190             else
    191             {
    192                 Modify(query[i].l,hash(a[query[i].l]),-1);
    193                 Modify(query[i].l,hash(query[i].r),1);
    194                 a[query[i].l] = query[i].r;
    195             }
    196         }
    197     }
    198     return 0;
    199 }
  • 相关阅读:
    使用Dictionary键值对判断字符串中字符出现次数
    Linq实现字符串拼接多条件查询
    js数据类型转换
    js前端数据类型检测typeof,instanceof,Object.prototype.toString.call
    moment.js格式化日期,获取前一个月的时间
    css 样式中height100%失效问题
    记一次react项目运行崩溃
    null和undefined区别
    windows腾讯云/阿里云服务器更换操作系统为linux
    csrf攻击原理和防御-生成token防御代码
  • 原文地址:https://www.cnblogs.com/kuangbin/p/3308118.html
Copyright © 2011-2022 走看看