K大数查询
本来是刷整体二分的,被这个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 }