zoukankan      html  css  js  c++  java
  • 洛谷P2617 Dynamic Rankings

    题意:带修区间第k大。

    具体来说,就是带修主席树模板题。

    解:唔...不离散化的话疯狂卡常都过不去,离散化就A了...虽然还是很慢。

    把主席树换成树状数组套动态开点线段树即可。

      1 #include <algorithm>
      2 #include <cstdio>
      3 
      4 const int N = 100010, M = 45000010;
      5 
      6 struct Node {
      7     int f, x, y, z;
      8 }node[N];
      9 
     10 int a[N], now[N], rt[N], tot, n, p[N], tp, X[N << 1], temp;
     11 int sum[M], ls[M], rs[M];
     12 char str[3];
     13 bool vis[N];
     14 
     15 inline void read(int &x) {
     16     x = 0;
     17     char c = getchar();
     18     while(c < '0' || c > '9') {
     19         c = getchar();
     20     }
     21     while(c >= '0' && c <= '9') {
     22         x = (x << 3) + (x << 1) + c - 48;
     23         c = getchar();
     24     }
     25     return;
     26 }
     27 
     28 void add(int p, int v, int l, int r, int &o) {
     29     if(!o) {
     30         o = ++tot;
     31     }
     32     if(l == r) {
     33         sum[o] += v;
     34         return;
     35     }
     36     int mid = (l + r) >> 1;
     37     if(p <= mid) {
     38         add(p, v, l, mid, ls[o]);
     39     }
     40     else {
     41         add(p, v, mid + 1, r, rs[o]);
     42     }
     43     sum[o] = sum[ls[o]] + sum[rs[o]];
     44     return;
     45 }
     46 
     47 inline void insert(int p, int v, int id) {
     48     for(register int i = id; i <= n; i += i & (-i)) {
     49         add(p, v, 1, temp, rt[i]);
     50     }
     51     return;
     52 }
     53 
     54 inline int ask(int k, int L, int R) {
     55     for(register int i = L - 1; i >= 1; i -= i & (-i)) {
     56         vis[i] = 1;
     57         now[i] = rt[i];
     58         p[++tp] = i;
     59     }
     60     for(register int i = R; i >= 1; i -= i & (-i)) {
     61         if(!vis[i]) {
     62             vis[i] = 1;
     63             now[i] = rt[i];
     64             p[++tp] = i;
     65         }
     66     }
     67     //printf("ask : %d %d  k = %d 
    ", L, R, k);
     68     int l = 1, r = temp;
     69     while(l < r) {
     70         int mid = (l + r) >> 1, s = 0;
     71         for(register int i = L - 1; i >= 1; i -= i & (-i)) {
     72             s -= *(sum + (*(ls + (*(now + i)))));
     73             //printf("s -= %d 
    ", sum[ls[now[i]]]);
     74         }
     75         for(register int i = R; i >= 1; i -= i & (-i)) {
     76             s += *(sum + (*(ls + (*(now + i)))));
     77             //printf("s += %d 
    ", sum[ls[now[i]]]);
     78         }
     79         //printf("%d %d s = %d k = %d 
    ", l, r, s, k);
     80         if(k <= s) {
     81             for(register int i = 1; i <= tp; i++) {
     82                 *(now + (*(p + i))) = *(ls + (*(now + (*(p + i)))));
     83             }
     84             r = mid;
     85         }
     86         else {
     87             for(register int i = 1; i <= tp; i++) {
     88                 *(now + (*(p + i))) = *(rs + (*(now + (*(p + i)))));
     89             }
     90             k -= s;
     91             l = mid + 1;
     92         }
     93     }
     94     for(register int i = 1; i <= tp; i++) {
     95         vis[p[i]] = 0;
     96     }
     97     tp = 0;
     98     return r;
     99 }
    100 
    101 int main() {
    102     int m;
    103     read(n);
    104     read(m);
    105     for(register int i = 1; i <= n; i++) {
    106         read(a[i]);
    107         X[++temp] = a[i];
    108     }
    109     for(register int i = 1; i <= m; i++) {
    110         scanf("%s", str);
    111         read(node[i].x);
    112         read(node[i].y);
    113         if(str[0] == 'Q') {
    114             read(node[i].z);
    115         }
    116         else {
    117             node[i].f = 1;
    118             X[++temp] = node[i].y;
    119         }
    120     }
    121     std::sort(X + 1, X + temp + 1);
    122     temp = std::unique(X + 1, X + temp + 1) - X - 1;
    123 
    124     /*for(int i = 1; i <= temp; i++) {
    125         printf("%d ", X[i]);
    126     }
    127     puts("");*/
    128 
    129     for(int i = 1; i <= n; i++) {
    130         a[i] = std::lower_bound(X + 1, X + temp + 1, a[i]) - X;
    131         insert(a[i], 1, i);
    132         //printf("insert : %d %d 
    ", a[i], i);
    133     }
    134     for(int i = 1; i <= m; i++) {
    135         if(node[i].f) {
    136             node[i].y = std::lower_bound(X + 1, X + temp + 1, node[i].y) - X;
    137         }
    138     }
    139     for(register int i = 1, x, y, z; i <= m; i++) {
    140         x = node[i].x;
    141         y = node[i].y;
    142         if(!node[i].f) {
    143             z = node[i].z;
    144             printf("%d
    ", X[ask(z, x, y)]);
    145         }
    146         else {
    147             insert(a[x], -1, x);
    148             insert(y, 1, x);
    149             a[x] = y;
    150         }
    151     }
    152     return 0;
    153 }
    AC代码
  • 相关阅读:
    [AST Babel] Babel Template
    [HTML5] Layout Reflow & thrashing
    [Cypress] Combine Custom Cypress Commands into a Single Custom Command
    errno , perror,strerror
    使用RMAN和控制文件备份删除归档日志的SHELL脚本--RED HAT 5 LINUX 64
    Documentation/ABI/testing/sysfs-block.txt
    003java面试笔记——【java基础篇】从团八百失败面试总结的java面试题(未完待续)
    How Many Tables
    NTP for Linux
    如何通过预加载器提升网页加载速度
  • 原文地址:https://www.cnblogs.com/huyufeifei/p/10322140.html
Copyright © 2011-2022 走看看