• [国家集训队]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);
    	}
     } 
    
  • 相关阅读:
    INSERT INTO ON DUPLICATE KEY UPDATE
    page to frame
    指定人提交
    在结构体嵌入接口
    排序 /src/sort/zfuncversion.go:136
    Modification should be made to copies of the returned MD.
    setTimeout 定时器的编号 实际延时比设定值更久的原因:最小延迟时间
    IOPS(Input/Output Operations Per Second)是一个用于计算机存储设备(如硬盘(HDD)、固态硬盘(SSD)或存储区域网络(SAN))性能测试的量测方式,可以视为是每秒的读写次数。和其他性能测试一样,存储设备制造商提出的IOPS不保证就是实际应用下的性能。
    Working Around Memory Leaks in Your Django Application
    celery 内存泄露
  • 原文地址:https://www.cnblogs.com/nibabadeboke/p/16096303.html
Copyright © 2020-2023  润新知