bzoj2653

来源:互联网 发布:java中常用io流类 编辑:程序博客网 时间:2024/05/21 17:19

可持久化。。其实就是让头结点做中位数,然后可持久,然后二分就好了,如果不太懂做一下1303就好了

#include<iostream>#include<algorithm>#include<cstdio>using namespace std;int n, q;struct treee{int son[2];int pmax[2], sum;treee(){pmax[0] = -1000000000, pmax[1] = -1000000000, sum = 0;}};struct point{int value, pos;};point p[20001];treee tree[400000];int tot = 0;int root[20001];void update(int now){int ls = tree[now].son[0]; int rs = tree[now].son[1];tree[now].pmax[0] = max(tree[now].pmax[0], tree[ls].pmax[0]);tree[now].pmax[0] = max(tree[now].pmax[0], tree[rs].pmax[0] + tree[ls].sum);tree[now].pmax[1] = max(tree[now].pmax[1], tree[rs].pmax[1]);tree[now].pmax[1] = max(tree[now].pmax[1], tree[ls].pmax[1] + tree[rs].sum);tree[now].sum = tree[ls].sum + tree[rs].sum;}void build(int &root, int ll, int rr,int pos){root = ++tot;if (ll == rr){if (ll!=pos)tree[root].pmax[0] = tree[root].pmax[1] = tree[root].sum = -1;elsetree[root].pmax[0] = tree[root].pmax[1] = tree[root].sum = 1;}else{int mid = (ll + rr) >> 1;build(tree[root].son[0], ll, mid,pos);build(tree[root].son[1], mid + 1, rr,pos);update(root);}}void update(int old, int &now, int ll, int rr, int pos){now = ++tot; tree[now] = tree[old]; tree[now].pmax[0] = -1000000000; tree[now].pmax[1] = -1000000000;if (ll == rr)tree[now].pmax[0] = tree[now].pmax[1] = tree[now].sum = 1;else{int mid = (ll + rr) >> 1; if (mid >= pos)update(tree[old].son[0], tree[now].son[0], ll, mid, pos);if (mid + 1 <= pos)update(tree[old].son[1], tree[now].son[1], mid + 1, rr, pos);update(now);}}int summ(int root, int ll, int rr, int l, int r){if (l > r)return 0;if (ll >= l&&rr <= r)return tree[root].sum;else{int mid = (ll + rr) >> 1;int lsum = 0;int  rsum = 0;if (mid>= l)lsum = summ(tree[root].son[0], ll, mid, l, r);if (mid + 1 <= r)rsum = summ(tree[root].son[1], mid + 1, rr, l, r);return lsum + rsum;}}int getpmax(int kind, int root, int ll, int rr, int l, int r){if (ll >= l&&rr <= r)return tree[root].pmax[kind];else{int mid = (ll + rr) >> 1;if (mid +1<=l)return getpmax(kind, tree[root].son[1], mid + 1, rr, l, r);if (mid >= r)return getpmax(kind, tree[root].son[0], ll, mid, l, r);if (!kind){int lmax = getpmax(kind, tree[root].son[0], ll, mid, l, r);lmax = max(lmax, summ(tree[root].son[0], ll, mid, l, r) + getpmax(kind, tree[root].son[1], mid + 1, rr, l, r));return lmax;}else{int rmax = getpmax(kind, tree[root].son[1], mid + 1, rr, l, r);rmax = max(rmax, summ(tree[root].son[1], mid + 1, rr, l, r) + getpmax(kind, tree[root].son[0], ll, mid, l, r));return rmax;}}}bool com(point a, point b){return a.value > b.value;}bool check(int pos,int a,int b,int c,int d){int sum = summ(root[pos], 1, n, b + 1, c - 1);int lmax = getpmax(1, root[pos], 1, n, a, b);int rmax = getpmax(0, root[pos], 1, n, c, d);return (sum + lmax + rmax) >=0;}int qq[5];int main(){scanf("%d", &n);for (int i = 1; i <=n; i++)scanf("%d", &p[i].value),p[i].pos=i;sort(p + 1,p + n + 1,com);build(root[1], 1, n,p[1].pos);for (int i = 2; i <= n; i++){update(root[i - 1], root[i], 1, n, p[i].pos);}int x = 0;scanf("%d", &q);for (int i = 0; i < q; i++){scanf("%d%d%d%d" , &qq[0], &qq[1], &qq[2], &qq[3]);for (int i = 0; i < 4; i++)qq[i] = (qq[i] + x) % n;sort(qq, qq + 4);int l = 1; int r = n;while (l < r){int mid = ((l + r) >> 1);if (check(mid, qq[0]+1, qq[1]+1, qq[2]+1, qq[3]+1))r = mid;elsel = mid+1;}x = p[r].value;printf("%d\n", x);}return 0;}

原创粉丝点击