[国家集训队]middle
作者:互联网
\(\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);
}
}
标签:return,rs,int,mid,middle,ls,ans,国家集训队 来源: https://www.cnblogs.com/nibabadeboke/p/16096303.html