二分答案,判断可不可行的方法如下:比当前元素小的值标记为-1,反之标记为1,然后a,b,c,d内存在区间使得和大于等于0表示可行。。。。。判断区间最大和可以用线段树区间合并。为了降低复杂度,要预先按值建立主席树。。。
#include <iostream> #include <queue> #include <stack> #include <map> #include <set> #include <bitset> #include <cstdio> #include <algorithm> #include <cstring> #include <climits> #include <cstdlib> #include <cmath> #include <time.h> #define maxn 20005 #define maxm 1000005 #define eps 1e-7 #define mod 998244353 #define INF 0x3f3f3f3f #define PI (acos(-1.0)) #define lowbit(x) (x&(-x)) #define mp make_pair //#define ls o<<1 //#define rs o<<1 | 1 //#define lson o<<1, L, mid //#define rson o<<1 | 1, mid+1, R #define pii pair<int, int> #pragma comment(linker, "/STACK:16777216") typedef long long LL; typedef unsigned long long ULL; //typedef int LL; using namespace std; LL qpow(LL a, LL b){LL res=1,base=a;while(b){if(b%2)res=res*base;base=base*base;b/=2;}return res;} LL powmod(LL a, LL b){LL res=1,base=a;while(b){if(b%2)res=res*base%mod;base=base*base%mod;b/=2;}return res;} // head // 2653 middle struct node { int lmax, rmax, sum; node *ch[2]; }pool[maxm], *tail; node *root[maxn], *init_root, *rt; pair<int, int> a[maxn]; int q[maxn]; int n, m; node* newnode(int t) { tail->sum = t; tail->ch[0] = tail->ch[1] = NULL; if(t == 1) tail->lmax = tail->rmax = 1; else tail->lmax = tail->rmax = 0; return tail++; } void pushup(node *o) { o->sum = o->ch[0]->sum + o->ch[1]->sum; o->lmax = max(o->ch[0]->lmax, o->ch[0]->sum + o->ch[1]->lmax); o->rmax = max(o->ch[1]->rmax, o->ch[1]->sum + o->ch[0]->rmax); } node* build(int L, int R) { if(L == R) return newnode(1); int mid = (L + R) >> 1; node *p = newnode(0); p->ch[0] = build(L, mid); p->ch[1] = build(mid+1, R); pushup(p); return p; } node* update(node *o, int L, int R, int id) { if(L == R) return newnode(-1); int mid = (L + R) >> 1; node *p = newnode(0); p->ch[0] = o->ch[0]; p->ch[1] = o->ch[1]; if(id <= mid) p->ch[0] = update(o->ch[0], L, mid, id); else p->ch[1] = update(o->ch[1], mid+1, R, id); pushup(p); return p; } void init() { tail = pool; } int query(node *o, int L, int R, int ql, int qr) { if(ql <= L && qr >= R) return o->sum; int mid = (L + R) >> 1, ans = 0; if(ql <= mid) ans += query(o->ch[0], L, mid, ql, qr); if(qr > mid) ans += query(o->ch[1], mid+1, R, ql, qr); return ans; } int query2(node *o, int L, int R, int ql, int qr) { if(ql == L && qr == R) return o->rmax; int mid = (L + R) >> 1; if(qr <= mid) return query2(o->ch[0], L, mid, ql, qr); else if(ql > mid) return query2(o->ch[1], mid+1, R, ql, qr); else return max(query2(o->ch[1], mid+1, R, mid+1, qr), query(o->ch[1], mid+1, R, mid+1, qr) + query2(o->ch[0], L, mid, ql, mid)); } int query3(node *o, int L, int R, int ql, int qr) { if(ql == L && qr == R) return o->lmax; int mid = (L + R) >> 1; if(qr <= mid) return query3(o->ch[0], L, mid, ql, qr); else if(ql > mid) return query3(o->ch[1], mid+1, R, ql, qr); else return max(query3(o->ch[0], L, mid, ql, mid), query(o->ch[0], L, mid, ql, mid) + query3(o->ch[1], mid+1, R, mid+1, qr)); } bool check(int x) { int t = lower_bound(a, a+n, mp(x, 0)) - a; if(t) rt = root[t-1]; else rt = init_root; int ans = 0; ans += query(rt, 0, n-1, q[1], q[2]); if(q[0] <= q[1]-1) ans += query2(rt, 0, n-1, q[0], q[1]-1); if(q[2]+1 <= q[3]) ans += query3(rt, 0, n-1, q[2]+1, q[3]); return ans >= 0; } void debug(node *o, int L, int R) { printf("%d %d %d %d %d\n", L, R, o->sum, o->lmax, o->rmax); if(L == R) return; int mid = (L + R) >> 1; debug(o->ch[0], L, mid); debug(o->ch[1], mid+1, R); } void work() { int x; scanf("%d", &n); for(int i = 0; i < n; i++) scanf("%d", &x), a[i] = mp(x, i); scanf("%d", &m); int ans = 0; sort(a, a+n); init_root = build(0, n-1); for(int i = 0; i < n; i++) { if(i) root[i] = update(root[i-1], 0, n-1, a[i].second); else root[i] = update(init_root, 0, n-1, a[i].second); } int res = 0; while(m--) { for(int i = 0; i < 4; i++) scanf("%d", &q[i]); for(int i = 0; i < 4; i++) q[i] = (q[i] + res) % n; sort(q, q+4); int bot = a[0].first, top = a[n-1].first, mid; while(top >= bot) { mid = (top + bot) >> 1; if(check(mid)) bot = mid+1, res = mid; else top = mid-1; } printf("%d\n", res); } } int main() { init(); work(); return 0; }