• 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

     绝望的主席树  

    这个动态查询快把我弄废了

    现在处于懵逼状态 ,对着大佬的板子敲的

    头疼欲裂 

    难受啊

    等改天对这个主席树的理解深入后再再写一下补充一下这个博客吧

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 const int maxn = 6e4 + 10;
      4 int a[maxn], h[maxn];
      5 int T[maxn], L[maxn << 5], R[maxn << 5], sum[maxn << 5];
      6 int s[maxn], n, m, tot;
      7 struct node {
      8     int l, r, k;
      9     int flag;
     10 } op[10010];
     11 int build(int l, int r) {
     12     int rt = (++tot);
     13     sum[rt] = 0;
     14     if (l != r) {
     15         int m = (l + r) >> 1;
     16         L[rt] = build(l, m);
     17         R[rt] = build(m + 1, r);
     18     }
     19     return rt;
     20 }
     21 int update(int pre, int l, int r, int x, int val) {
     22     int rt = (++tot);
     23     L[rt] = L[pre], R[rt] = R[pre], sum[rt] = sum[pre] + val;
     24     if (l < r) {
     25         int m = (l + r) >> 1;
     26         if (x <= m) L[rt] = update(L[pre], l, m, x, val);
     27         else R[rt] = update(R[pre], m + 1, r, x, val);
     28     }
     29     return rt;
     30 }
     31 int lowbit(int x) {
     32     return x & (-x);
     33 }
     34 int used[maxn];
     35 void add(int x, int pos, int val) {
     36     while(x <= n) {
     37         s[x] = update(s[x], 1, m, pos, val);
     38         x += lowbit(x);
     39     }
     40 }
     41 int  Sum(int x) {
     42     int ret = 0;
     43     while(x > 0) {
     44         ret += sum[L[used[x]]];
     45         x -= lowbit(x);
     46     }
     47     return ret;
     48 }
     49 int query(int u, int v, int lr, int rr, int l, int r, int k) {
     50     if (l >= r) return l;
     51     int m = (l + r) >> 1;
     52     int temp = Sum(v) - Sum(u) + sum[L[rr]] - sum[L[lr]];
     53     if (temp >= k ) {
     54         for (int i = u ; i ; i -= lowbit(i)) used[i] = L[used[i]];
     55         for (int i = v ; i ; i -= lowbit(i)) used[i] = L[used[i]];
     56         return query(u, v, L[lr], L[rr], l, m, k);
     57     } else {
     58         for (int i = u ; i ; i -= lowbit(i)) used[i] = R[used[i]];
     59         for (int i = v ; i ; i -= lowbit(i)) used[i] = R[used[i]];
     60         return query(u, v, R[lr], R[rr], m + 1, r, k - temp);
     61     }
     62 }
     63 void modify(int x, int p, int d) {
     64     while(x <= n) {
     65         s[x] = update(s[x], 1, m, p, d);
     66         x += lowbit(x);
     67     }
     68 }
     69 int main() {
     70     int t;
     71     scanf("%d", &t);
     72     while(t--) {
     73         int q;
     74         scanf("%d%d", &n, &q);
     75         tot = 0;
     76         m = 0;
     77         for(int i = 1; i <= n; i++) {
     78             scanf("%d", &a[i]);
     79             h[++m] = a[i];
     80         }
     81         for(int i = 0; i < q; i++) {
     82             char s[10];
     83             scanf("%s", s);
     84             if(s[0] == 'Q') {
     85                 scanf("%d%d%d", &op[i].l, &op[i].r, &op[i].k);
     86                 op[i].flag = 1;
     87             } else {
     88                 scanf("%d%d", &op[i].l, &op[i].r);
     89                 op[i].flag = 0;
     90                 h[++m] = op[i].r;
     91             }
     92         }
     93         sort(h + 1, h + 1 + m);
     94         int mm = unique(h + 1, h + 1 + m) - h - 1;
     95         m = mm;
     96         T[0] = build(1, m);
     97         for(int i = 1; i <= n; i++)
     98             T[i] = update(T[i - 1], 1, m, lower_bound(h + 1, h + 1 + m, a[i]) - h, 1);
     99         for(int i = 1; i <= n; i++)
    100             s[i] = T[0];
    101         for(int i = 0; i < q; i++) {
    102             if(op[i].flag) {
    103                 for(int j = op[i].l - 1; j; j -= lowbit(j))
    104                     used[j] = s[j];
    105                 for(int j = op[i].r; j; j -= lowbit(j))
    106                     used[j] = s[j];
    107                 printf("%d
    ", h[query(op[i].l - 1, op[i].r, T[op[i].l - 1], T[op[i].r], 1, m, op[i].k)]);
    108             } else {
    109                 modify(op[i].l, lower_bound(h + 1, h + 1 + m, a[op[i].l]) - h, -1);
    110                 modify(op[i].l, lower_bound(h + 1, h + 1 + m, op[i].r) - h, 1);
    111                 a[op[i].l] = op[i].r;
    112             }
    113         }
    114     }
    115     return 0;
    116 }
  • 相关阅读:
    多点触控版的驱动安装
    模板类的继承
    c++大整数运算
    RHEL6单用户模式切换
    Dlna相关开源项目收集整理
    给我的当前RHEL6新增一块硬盘!
    交叉编译libconv
    OSCam学习记录
    Android中的应用!!!!
    Elf文件格式学习笔记
  • 原文地址:https://www.cnblogs.com/qldabiaoge/p/9119102.html
Copyright © 2020-2023  润新知