解题:国家集训队 Middle
求中位数的套路:二分,大于等于的设为1,小于的设为-1
于是可以从小到大排序后依次加入可持久化线段树,这样每次只会变化一个位置
那左右端点是区间怎么办?
先把中间的算上,然后维护每个区间左右两侧最大子段和,左右和右左拼起来即可
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=,M=1e7+,inf=1e9;
int num[N],root[N],son[M][],sum[M],lsum[M],rsum[M],qry[];
int n,m,t1,t2,t3,t4,rd,tot,ans; pair<int,int> mem[N];
void Pushup(int nde)
{
int ls=son[nde][],rs=son[nde][];
sum[nde]=sum[ls]+sum[rs];
lsum[nde]=max(lsum[ls],sum[ls]+lsum[rs]);
rsum[nde]=max(rsum[rs],sum[rs]+rsum[ls]);
}
int Pre(int l,int r)
{
int nde=++tot;
if(l==r)
sum[nde]=lsum[nde]=rsum[nde]=;
else
{
int mid=(l+r)>>;
son[nde][]=Pre(l,mid);
son[nde][]=Pre(mid+,r);
Pushup(nde);
}
return nde;
}
int Insert(int pre,int l,int r,int pos,int tsk)
{
int nde=++tot;
son[nde][]=son[pre][];
son[nde][]=son[pre][];
if(l==r)
sum[nde]=lsum[nde]=rsum[nde]=tsk;
else
{
int mid=(l+r)>>;
if(pos<=mid) son[nde][]=Insert(son[pre][],l,mid,pos,tsk);
else son[nde][]=Insert(son[pre][],mid+,r,pos,tsk); Pushup(nde);
}
return nde;
}
int Query1(int nde,int l,int r,int ll,int rr)
{
if(l==ll&&r==rr)
return sum[nde];
else
{
int mid=(l+r)>>;
if(mid>=rr) return Query1(son[nde][],l,mid,ll,rr);
else if(mid<ll) return Query1(son[nde][],mid+,r,ll,rr);
else return Query1(son[nde][],l,mid,ll,mid)+Query1(son[nde][],mid+,r,mid+,rr);
}
}
int Query2(int nde,int l,int r,int ll,int rr)
{
if(l==ll&&r==rr)
return lsum[nde];
else
{
int mid=(l+r)>>;
if(mid>=rr) return Query2(son[nde][],l,mid,ll,rr);
else if(mid<ll) return Query2(son[nde][],mid+,r,ll,rr);
else return max(Query2(son[nde][],l,mid,ll,mid),Query1(son[nde][],l,mid,ll,mid)+Query2(son[nde][],mid+,r,mid+,rr));
}
}
int Query3(int nde,int l,int r,int ll,int rr)
{
if(l==ll&&r==rr)
return rsum[nde];
else
{
int mid=(l+r)>>;
if(mid>=rr) return Query3(son[nde][],l,mid,ll,rr);
else if(mid<ll) return Query3(son[nde][],mid+,r,ll,rr);
else return max(Query3(son[nde][],mid+,r,mid+,rr),Query1(son[nde][],mid+,r,mid+,rr)+Query3(son[nde][],l,mid,ll,mid));
}
}
bool Check(int x)
{
int ret=;
if(qry[]+<=qry[]-) ret+=Query1(root[x],,n,qry[]+,qry[]-);
ret+=Query3(root[x],,n,qry[],qry[])+Query2(root[x],,n,qry[],qry[]);
return ret>=;
}
int main()
{
scanf("%d",&n);
for(int i=;i<=n;i++)
scanf("%d",&num[i]),mem[i]=make_pair(num[i],i);
sort(mem+,mem++n),root[]=Pre(,n);
for(int i=;i<=n;i++)
root[i]=Insert(root[i-],,n,mem[i-].second,-);
scanf("%d",&m);
for(int i=;i<=m;i++)
{
for(int j=;j<=;j++)
scanf("%d",&rd),qry[j]=(rd+ans)%n+;
sort(qry+,qry+);
int l=,r=n,lst=;
while(l<=r)
{
int mid=(l+r)>>;
if(Check(mid)) l=mid+,lst=mid;
else r=mid-;
}
printf("%d\n",ans=mem[lst].first);
}
return ;
}
解题:国家集训队 Middle的更多相关文章
- [国家集训队]middle 解题报告
[国家集训队]middle 主席树的想法感觉挺妙的,但是这题数据范围这么小,直接分块草过去不就好了吗 二分是要二分的,把\(<x\)置\(-1\),\(\ge x\)的置\(1\),于是我们需要 ...
- [国家集训队]middle
[国家集训队]middle 题目 解法 开\(n\)颗线段树,将第\(i\)颗线段树中大于等于第\(i\)小的数权值赋为1,其他的则为-1,对于每个区间维护一个区间和,最大前缀和,最大后缀和. 然后二 ...
- P2839 [国家集训队]middle
P2839 [国家集训队]middle 好妙的题啊,,,, 首先二分一个答案k,把数列里>=k的数置为1,=0就是k>=中位数,<0就是k<中位数 数列的最大和很好求哇 左边的 ...
- CF484E Sign on Fence && [国家集训队]middle
CF484E Sign on Fence #include<bits/stdc++.h> #define RG register #define IL inline #define _ 1 ...
- 【LG2839】[国家集训队]middle
[LG2839][国家集训队]middle 题面 洛谷 题解 按照求中位数的套路,我们二分答案\(mid\),将大于等于\(mid\)的数设为\(1\),否则为\(-1\). 若一个区间和大于等于\( ...
- BZOJ.2653.[国家集训队]middle(可持久化线段树 二分)
BZOJ 洛谷 求中位数除了\(sort\)还有什么方法?二分一个数\(x\),把\(<x\)的数全设成\(-1\),\(\geq x\)的数设成\(1\),判断序列和是否非负. 对于询问\(( ...
- luogu2839 [国家集训队]middle
题目链接:洛谷 题目大意:给定一个长度为$n$的序列,每次询问左端点在$[a,b]$,右端点在$[c,d]$的所有子区间的中位数的最大值.(强制在线) 这里的中位数定义为,对于一个长度为$n$的序列排 ...
- [洛谷P2839][国家集训队]middle
题目大意:给你一个长度为$n$的序列$s$.$Q$个询问,问在$s$中的左端点在$[a,b]$之间,右端点在$[c,d]$之间的子段中,最大的中位数. 强制在线. 题解:区间中位数?二分答案,如果询问 ...
- Luogu 2839 [国家集训队]middle
感觉这题挺好的. 首先对于中位数最大有一个很经典的处理方法就是二分,每次二分一个数组中的下标$mid$,然后我们把$mid$代回到原来的数组中检查,如果一个数$a_{i} \geq mid$,那么就把 ...
随机推荐
- 20155320《网络对抗》Exp2 后门原理与实践
20155320<网络对抗>Exp2 后门原理与实践 [实验内容] (3.5分) (1)使用netcat获取主机操作Shell,cron启动 (2)使用socat获取主机操作Shell, ...
- linux下使用软连接之案例二
在笔者的上一篇文章介绍过怎么通过linux的软连接在不修改上传代码的情况下,将上传到项目路径下的图片改为上传到项目外面,防止重新部署后图片被删除了.同时还可以直接通过类似访问静态资源的方 ...
- FormData 数据转化为 json 数据
两种方法 <!-- 实例:将 FormData 转化为 json --> <meta charset="utf-8"/> <form enctype= ...
- kvm虚拟化二: 字符界面管理及 无人值守安装
1. 安装必要工具yum install / tigervnc //vnc远程桌面客户端 virt-viewer //虚拟机查看器 2.安装虚拟机virt-install / -n 名字 //虚拟机名 ...
- P4292 [WC2010]重建计划
无脑上二分+淀粉质完事了 每个子树算的时候把儿子按照最长路径从小到大依次做,和前面的单调队列算一波,每个儿子的复杂度不超过这个子树大小 // luogu-judger-enable-o2 #inclu ...
- 并发系列(一)-----synchronized关键字
一 简介 说到并发不得不提的synchronized,synchronized关键字是元老级别的角色.在Java SE 1.6之前synchronized被称为是重量,在1.6之后对同步进行了一系列的 ...
- PAT甲级题解-1097. Deduplication on a Linked List (25)-链表的删除操作
给定一个链表,你需要删除那些绝对值相同的节点,对于每个绝对值K,仅保留第一个出现的节点.删除的节点会保留在另一条链表上.简单来说就是去重,去掉绝对值相同的那些.先输出删除后的链表,再输出删除了的链表. ...
- svn命令行创建和删除分支和tags
首页 分类首页 目录 原文: http://blog.csdn.net/yangzhongxuan/article/details/7519948 http://zccst.iteye.com/b ...
- LeetCode 70. Climbing Stairs爬楼梯 (C++)
题目: You are climbing a stair case. It takes n steps to reach to the top. Each time you can either cl ...
- 刚做了个实验,验证++和!和printf的先后次序