bzoj 4552
Posted zjoiak
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj 4552相关的知识,希望对你有一定的参考价值。
二分 + 线段树
二分一个值 x, 讲原序列转化为01序列
1表示该数>x, 0表示改数<x;
线段树维护区间和进行判断
#include <bits/stdc++.h> const int N = 1e5 + 10; #define gc getchar() int n, m, Q; int A[N], B[N]; int S[N << 2], W[N << 2], F[N << 2]; int opt[N], lask[N], rask[N]; int js; inline int read() { int x = 0; char c = gc; while(c < ‘0‘ || c > ‘9‘) c = gc; while(c >= ‘0‘ && c <= ‘9‘) x = x * 10 + c - ‘0‘, c = gc; return x; } #define lson jd << 1 #define rson jd << 1 | 1 void Build_size(int l, int r, int jd) { S[jd] = r - l + 1; if(l == r) return ; int mid = (l + r) >> 1; Build_size(l, mid, lson); Build_size(mid + 1, r, rson); } void Build_tree(int l, int r, int jd) { F[jd] = -1; if(l == r) {W[jd] = B[l]; return ;} int mid = (l + r) >> 1; Build_tree(l, mid, lson); Build_tree(mid + 1, r, rson); W[jd] = W[lson] + W[rson]; } void Down(int jd) { F[lson] = F[rson] = F[jd]; W[lson] = S[lson] * F[jd], W[rson] = S[rson] * F[jd]; F[jd] = -1; } int Answer; void Sec_A(int l, int r, int jd, int x, int y) { if(x > y) return ; if(x <= l && r <= y) {Answer += W[jd]; return ;} if(F[jd] != -1) Down(jd); int mid = (l + r) >> 1; if(x <= mid) Sec_A(l, mid, lson, x, y); if(y > mid) Sec_A(mid + 1, r, rson, x, y); } void Sec_G(int l, int r, int jd, int x, int y, int how) { if(x > y) return ; if(x <= l && r <= y) { F[jd] = how; W[jd] = S[jd] * how; return ; } if(F[jd] != -1) Down(jd); int mid = (l + r) >> 1; if(x <= mid) Sec_G(l, mid, lson, x, y, how); if(y > mid) Sec_G(mid + 1, r, rson, x, y, how); W[jd] = W[lson] + W[rson]; } inline bool See(int x) { for(int i = 1; i <= n; i ++) B[i] = (A[i] >= x); Build_tree(1, n, 1); for(int i = 1; i <= m; i ++) { Answer = 0; Sec_A(1, n, 1, lask[i], rask[i]); int sum = Answer; if(!opt[i]) { Sec_G(1, n, 1, rask[i] - sum + 1, rask[i], 1); Sec_G(1, n, 1, lask[i], rask[i] - sum, 0); } else { Sec_G(1, n, 1, lask[i], lask[i] + sum - 1, 1); Sec_G(1, n, 1, lask[i] + sum, rask[i], 0); } } Answer = 0; Sec_A(1, n, 1, Q, Q); return Answer; } int main() { n = read(), m = read(); for(int i = 1; i <= n; i ++) A[i] = read(); for(int i = 1; i <= m; i ++) opt[i] = read(), lask[i] = read(), rask[i] = read(); Q = read(); Build_size(1, n, 1); int L = 1, R = n, Ans(0); while(L <= R) { int Mid = (L + R) >> 1; if(See(Mid)) L = Mid + 1, Ans = Mid; else R = Mid - 1; } std:: cout << Ans; return 0; }
以上是关于bzoj 4552的主要内容,如果未能解决你的问题,请参考以下文章
bzoj千题计划128:bzoj4552: [Tjoi2016&Heoi2016]排序