東風汽車公佈 2021 年財報:新能源車型銷量達 16.1 萬,同比增長 260%
阿新 • • 發佈:2022-04-02
\(\text{Solution}\)
發現大於中位數的數的個數是大於或等於小於中位數的個數的,所以就可以二分答案。
把大於等於\(mid\)的數變成\(1\),其餘變為\(-1\)。
用主席樹儲存在每個不同\(mid\)下樹的形態,這樣我們只需維護區間的字首,字尾最大值和區間和即可。
\(\text{Code}\)
#include<cstdio> #include<algorithm> #define LL long long using namespace std; const int N = 2e4 + 5; int size,n,rt[N],m; LL q[5],ans; struct nd{LL z;int id;}a[N]; struct tree{int lz,rz,z,ls,rs;}f[N * 30]; bool cmp(nd x,nd y){return x.z < y.z;} void build(int &p,int l,int r) { p = ++size,f[p] = tree{r - l + 1,r - l + 1,r - l + 1,0,0}; if (l == r) return; int mid = l + r >> 1; build(f[p].ls,l,mid),build(f[p].rs,mid + 1,r); } void update(int &p1,int p2,int l,int r,int u) { p1 = ++size,f[p1].ls = f[p2].ls,f[p1].rs = f[p2].rs; if (l == r) return f[p1] = tree{-1,-1,-1,0,0},void(); int mid = l + r >> 1; if (u <= mid) update(f[p1].ls,f[p2].ls,l,mid,u); else update(f[p1].rs,f[p2].rs,mid + 1,r,u); int ls = f[p1].ls,rs = f[p1].rs; f[p1].z = f[ls].z + f[rs].z,f[p1].lz = max(f[ls].lz,f[rs].lz + f[ls].z); f[p1].rz = max(f[rs].rz,f[ls].rz + f[rs].z); } int query(int p,int l,int r,int L,int R) { if (L <= l && r <= R) return f[p].z; int mid = l + r >> 1,tmp = 0; if (L <= mid) tmp = query(f[p].ls,l,mid,L,R); if (R > mid) tmp += query(f[p].rs,mid + 1,r,L,R); return tmp; } int queryl(int p,int l,int r,int L,int R) { if (L <= l && r <= R) return f[p].lz; int mid = l + r >> 1; if (R <= mid) return queryl(f[p].ls,l,mid,L,R); if (L > mid) return queryl(f[p].rs,mid + 1,r,L,R); return max(queryl(f[p].ls,l,mid,L,R),query(f[p].ls,l,mid,L,R) + queryl(f[p].rs,mid + 1,r,L,R)); } int queryr(int p,int l,int r,int L,int R) { if (L <= l && r <= R) return f[p].rz; int mid = l + r >> 1; if (R <= mid) return queryr(f[p].ls,l,mid,L,R); if (L > mid) return queryr(f[p].rs,mid + 1,r,L,R); return max(queryr(f[p].rs,mid + 1,r,L,R),queryr(f[p].ls,l,mid,L,R) + query(f[p].rs,mid + 1,r,L,R)); } int main() { scanf("%d",&n); for (int i = 1; i <= n; i++) scanf("%lld",&a[i].z),a[i].id = i; sort(a + 1,a + 1 + n,cmp),build(rt[1],1,n); for (int i = 1; i < n; i++) update(rt[i + 1],rt[i],1,n,a[i].id); scanf("%d",&m); for (int i = 1; i <= m; i++) { scanf("%lld%lld%lld%lld",&q[0],&q[1],&q[2],&q[3]); for (int j = 0; j < 4; j++) q[j] = (q[j] + ans) % n + 1LL; sort(q,q + 4); int l = 1,r = n; while (l <= r) { int mid = l + r >> 1,x1 = query(rt[mid],1,n,q[1] + 1,q[2] - 1); int x2 = queryr(rt[mid],1,n,q[0],q[1]),x3 = queryl(rt[mid],1,n,q[2],q[3]); if (x1 + x2 + x3 >= 0) ans = mid,l = mid + 1; else r = mid - 1; } ans = a[ans].z,printf("%lld\n",ans); } }