K大数查询 HYSBZ - 3110

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", 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", n - ans[i] + 1);
93     }
94 }
树状数组维护

 

posted @ 2018-01-21 16:51  yijiull  阅读(250)  评论(0编辑  收藏  举报