HYSBZ 2653middle(二分+主席树)

来源:互联网 发布:linux报错ld返回1 编辑:程序博客网 时间:2024/06/05 15:43

二分+主席树,挺神奇的做法

//#include <bits/stdc++.h>#include <iostream>#include <cstdio>#include <cmath>#include <cstring>#include <algorithm>using namespace std;#pragma comment(linker, "/STACK:102400000,102400000")#define LL long long #define pii pair<int, int>#define MP make_pair//#define ls i << 1//#define rs ls | 1#define md (ll + rr >> 1)#define lson ll, md, ls#define rson md + 1, rr, rs#define mod 1000000007#define inf 0x3f3f3f3f#define N 50020#define M 500010struct node{int v, id;void input(int i){scanf("%d", &v);id = i;}bool operator < (const node &b) const {return v < b.v;}};node a[N];int q[4], rt[N], tot, ch[N*30][2], n;int sum[N*30], lmx[N*30], rmx[N*30];void copy(int k, int i){ch[k][0] = ch[i][0], ch[k][1] = ch[i][1];sum[k] = sum[i], lmx[k] = lmx[i], rmx[k] = rmx[i];}void push_up(int i){sum[i] = sum[ch[i][0]] + sum[ch[i][1]];lmx[i] = max(lmx[ch[i][0]], sum[ch[i][0]] + lmx[ch[i][1]]);rmx[i] = max(rmx[ch[i][1]], sum[ch[i][1]] + rmx[ch[i][0]]);}int build(int ll, int rr){int k = ++tot;ch[k][0] = ch[k][1] = 0;if(ll == rr){sum[k] = lmx[k] = rmx[k] = 1;return k;}ch[k][0] = build(ll, md);ch[k][1] = build(md + 1, rr);push_up(k);return k;}int update(int x, int v, int ll, int rr, int i){int k = ++tot;copy(k, i);if(ll == rr){sum[k] = lmx[k] = rmx[k] = v;return k;}if(x <= md) ch[k][0] = update(x, v, ll, md, ch[i][0]);else ch[k][1] = update(x, v, md + 1, rr, ch[i][1]);push_up(k);return k;}int query(int l, int r, int ll, int rr, int i){if(l > r) return 0;if(l <= ll && r >= rr)return sum[i];if(r <= md) return query(l, r, ll, md, ch[i][0]);else if(l > md) return query(l, r, md + 1, rr, ch[i][1]);else return query(l, md, ll, md, ch[i][0]) + query(md + 1, r, md + 1, rr, ch[i][1]);}int query_lmx(int l, int r, int ll, int rr, int i){if(l > r) return 0;if(l <= ll && r >= rr)return lmx[i];if(r <= md) return query_lmx(l, r, ll, md, ch[i][0]);else if(l > md) return query_lmx(l, r, md + 1, rr, ch[i][1]);else{return max(query_lmx(l, md, ll, md, ch[i][0]), query(l, md, ll, md, ch[i][0]) + query_lmx(md + 1, r, md + 1, rr, ch[i][1]));}}int query_rmx(int l, int r, int ll, int rr, int i){if(l > r) return 0;if(l <= ll && r >= rr)return rmx[i];if(r <= md) return query_rmx(l, r, ll, md, ch[i][0]);else if(l > md) return query_rmx(l, r, md + 1, rr, ch[i][1]);else{return max(query_rmx(l, md, ll, md, ch[i][0]) + query(md + 1, r, md + 1, rr, ch[i][1]), query_rmx(md + 1, r, md + 1, rr, ch[i][1]));}}bool check(int m){int u = q[0], v = q[1], w = q[2], x = q[3];int ret = query_rmx(u, v, 1, n, rt[m]);ret += query(v + 1, w - 1, 1, n, rt[m]);ret += query_lmx(w, x, 1, n, rt[m]);return ret >= 0;}int main(){scanf("%d", &n);for(int i = 1; i <= n; ++i)a[i].input(i);sort(a + 1, a + 1 + n);rt[1] = build(1, n);for(int i = 2; i <= n; ++i)rt[i] = update(a[i-1].id, -1, 1, n, rt[i-1]);int ans = 0, m;scanf("%d", &m);while(m--){for(int i = 0; i < 4; ++i){scanf("%d", &q[i]);q[i] = (1LL * q[i] + ans) % n;q[i]++;}sort(q, q + 4);int L = 1, R = n;while(L < R){int mid = (L + R) >> 1;if(!check(mid))R = mid;else L = mid + 1;}if(!check(L)) L--;printf("%d\n", a[L].v);ans = a[L].v;}return 0;}


0 0
原创粉丝点击