zoukankan      html  css  js  c++  java
  • K大数查询 HYSBZ

    K大数查询

    HYSBZ - 3110

    本来是刷整体二分的,被这个sb题折腾了一下午,用cin就RE, 用scanf就过了=_=

    收获就是偶然学到了树状数组区间修改区间查询的写法吧。。。

      1 #include <iostream>
      2 #include <cstring>
      3 #include <cstdio>
      4 using namespace std;
      5 #define LL long long 
      6 const int maxn = 1e5 + 10;
      7 const int maxq = 5e4 + 10;
      8 struct Qry{
      9     int a, b;
     10     LL c;
     11     int id;
     12     Qry(int a = 0, int b = 0, LL c = 0, int id = 0):
     13         a(a), b(b), c(c), id(id){}
     14 }q[maxq], q1[maxq], q2[maxq];
     15 
     16 
     17 struct Seg{
     18     LL sum[maxn<<2], add[maxn<<2];
     19     void init(){
     20         memset(add, 0, sizeof add);
     21         memset(sum, 0, sizeof sum);
     22     }
     23     void pushup(int rt){
     24         sum[rt] = sum[rt<<1] + sum[rt<<1|1];
     25     }
     26     void pushdown(int rt, int m){
     27         if(add[rt]){
     28             sum[rt<<1] += (m - (m>>1)) * add[rt];
     29             sum[rt<<1|1] += (m >> 1) * add[rt];
     30             add[rt<<1] += add[rt];
     31             add[rt<<1|1] += add[rt];
     32             add[rt] = 0;
     33         }
     34     }
     35 
     36     void update(int L, int R, int v, int l, int r, int rt){
     37         if(L <= l && r <= R){
     38             sum[rt] += v * (r - l + 1);
     39             add[rt] += v;
     40             return;
     41         }
     42         pushdown(rt, r - l + 1);
     43         int m = (l + r) >> 1;
     44         if(L <= m) update(L, R, v, l, m, rt<<1);
     45         if(R > m) update(L, R, v, m + 1, r, rt<<1|1);
     46         pushup(rt);
     47     }
     48 
     49     LL query(int L, int R, int l, int r, int rt){
     50         if(L <= l && r <= R){
     51             return sum[rt];
     52         }
     53         pushdown(rt, r - l + 1);
     54         int m = (l + r) >> 1;
     55         LL res = 0;
     56         if(L <= m) res += query(L, R, l, m, rt<<1);
     57         if(R > m) res += query(L, R, m + 1, r, rt<<1|1);
     58         return res;
     59     }
     60 }seg;
     61 int ans[maxq];
     62 int n;
     63 void solve(int L, int R, int l, int r){
     64     if(L > R) return;
     65     if(l == r){
     66         for(int i = L; i <= R; i++){
     67             if(q[i].id > 0) ans[q[i].id] = l;
     68         }
     69         return;
     70     }
     71     int m = (l + r) >> 1;
     72     int f = 0, g = 0;
     73     for(int i = L; i <= R; i++){
     74         if(q[i].id < 0){
     75             if(q[i].c <= m){
     76                 seg.update(q[i].a, q[i].b, 1, 1, n, 1);
     77                 q1[f++] = q[i];
     78             }else q2[g++] = q[i];
     79         }else{
     80             LL temp = seg.query(q[i].a, q[i].b, 1, n, 1);
     81             if(temp >= q[i].c) q1[f++] = q[i];
     82             else{
     83                 q[i].c -= temp;
     84                 q2[g++] = q[i];
     85             }
     86         }
     87     }
     88     for(int i = 0; i < f; i++) if(q1[i].id < 0) seg.update(q1[i].a, q1[i].b, -1, 1, n, 1);
     89     memcpy(q + L, q1, f * sizeof(Qry));
     90     memcpy(q + L + f, q2, g * sizeof(Qry));
     91     solve(L, L + f - 1, l, m);
     92     solve(L + f, R, m + 1, r);
     93 }
     94 
     95 int main(){
     96     int m;
     97     while(scanf("%d %d", &n, &m) != EOF){
     98         int op, a, b;
     99         LL c;
    100         seg.init();
    101         int cnt = 0;
    102         for(int i = 1; i <= m; i++){
    103             cin>>op>>a>>b>>c;
    104             if(op == 1){
    105                 q[i] = Qry(a, b, n + 1LL - c, -1);
    106             }else{
    107                 q[i] = Qry(a, b, c, ++cnt);
    108             }
    109         }
    110         solve(1, m, 1, n * 2LL + 1);
    111         for(int i = 1; i <= cnt; i++) printf("%d
    ", n - ans[i] + 1);
    112     }
    113 }
    线段树维护
     1 #include <iostream>
     2 #include <cstring>
     3 #include <cstdio>
     4 using namespace std;
     5 #define LL long long 
     6 const int maxn = 1e5 + 10;
     7 const int maxq = 1e5 + 10;
     8 struct Qry{
     9     int a, b;
    10     LL c;
    11     int id;
    12     Qry(int a = 0, int b = 0, LL c = 0, int id = 0):
    13         a(a), b(b), c(c), id(id){}
    14 }q[maxq], q1[maxq], q2[maxq];
    15 //树状数组区间修改区间求和 http://blog.csdn.net/blackjack_/article/details/74997479
    16 struct Bit{
    17     int n;
    18     LL c1[maxn], c2[maxn];
    19     void init(int _n){
    20         n = _n;
    21         memset(c1, 0, sizeof(c1));
    22         memset(c2, 0, sizeof(c2));
    23     }
    24     void add(int x,LL add){  
    25         for(int i=x;i<=n;i+=i&(-i)){  
    26             c1[i]+=add;  
    27             c2[i]+=x*add;  
    28         }  
    29     }  
    30     LL sum(int x){  
    31         LL ans=0;  
    32         for(int i=x;i>0;i-=i&(-i)){  
    33             ans+=(x+1)*c1[i]-c2[i];  
    34         }  
    35         return ans;  
    36     } 
    37 }bit;
    38 int ans[maxq];
    39 int n;
    40 void solve(int L, int R, int l, int r){
    41     if(L > R) return;
    42     if(l == r){
    43         for(int i = L; i <= R; i++){
    44             if(q[i].id > 0) ans[q[i].id] = l;
    45         }
    46         return;
    47     }
    48     int m = (l + r) >> 1;
    49     int f = 0, g = 0;
    50     for(int i = L; i <= R; i++){
    51         if(q[i].id < 0){
    52             if(q[i].c <= m){
    53                 bit.add(q[i].a, 1LL);
    54                 bit.add(q[i].b+1, -1LL);
    55                 q1[f++] = q[i];
    56             }else q2[g++] = q[i];
    57         }else{
    58             LL temp = bit.sum(q[i].b) - bit.sum(q[i].a - 1);
    59             if(temp >= q[i].c) q1[f++] = q[i];
    60             else{
    61                 q[i].c -= temp;
    62                 q2[g++] = q[i];
    63             }
    64         }
    65     }
    66     for(int i = 0; i < f; i++) if(q1[i].id < 0 && q1[i].c <= m) {
    67         bit.add(q1[i].a, -1);
    68         bit.add(q1[i].b + 1, 1);
    69     }
    70     memcpy(q + L, q1, f * sizeof(Qry));
    71     memcpy(q + L + f, q2, g * sizeof(Qry));
    72     solve(L, L + f - 1, l, m);
    73     solve(L + f, R, m + 1, r);
    74 }
    75 
    76 int main(){
    77     int m;
    78     while(scanf("%d %d", &n, &m)!= EOF){
    79         int op, a, b;
    80         LL c;
    81         bit.init(n);
    82         int cnt = 0;
    83         for(int i = 1; i <= m; i++){
    84             cin>>op>>a>>b>>c;
    85             if(op == 1){
    86                 q[i] = Qry(a, b, n + 1LL - c, -1);
    87             }else{
    88                 q[i] = Qry(a, b, c, ++cnt);
    89             }
    90         }
    91         solve(1, m, 1, n * 2LL + 1);
    92         for(int i = 1; i <= cnt; i++) printf("%d
    ", n - ans[i] + 1);
    93     }
    94 }
    树状数组维护
  • 相关阅读:
    圣战 [奇环, 树上差分]
    花火之声不闻于耳 [线段树]
    SP2878 KNIGHTS
    P5300 [GXOI/GZOI2019]与或和 [单调栈]
    Speike [线段树, 动态规划]
    Jerry [动态规划]
    JSON对象
    正则书写
    flex布局实践
    数组对象的深拷贝与浅拷贝
  • 原文地址:https://www.cnblogs.com/yijiull/p/8324723.html
Copyright © 2011-2022 走看看