题面

求中位数的套路:二分,大于等于的设为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的更多相关文章

  1. [国家集训队]middle 解题报告

    [国家集训队]middle 主席树的想法感觉挺妙的,但是这题数据范围这么小,直接分块草过去不就好了吗 二分是要二分的,把\(<x\)置\(-1\),\(\ge x\)的置\(1\),于是我们需要 ...

  2. [国家集训队]middle

    [国家集训队]middle 题目 解法 开\(n\)颗线段树,将第\(i\)颗线段树中大于等于第\(i\)小的数权值赋为1,其他的则为-1,对于每个区间维护一个区间和,最大前缀和,最大后缀和. 然后二 ...

  3. P2839 [国家集训队]middle

    P2839 [国家集训队]middle 好妙的题啊,,,, 首先二分一个答案k,把数列里>=k的数置为1,=0就是k>=中位数,<0就是k<中位数 数列的最大和很好求哇 左边的 ...

  4. CF484E Sign on Fence && [国家集训队]middle

    CF484E Sign on Fence #include<bits/stdc++.h> #define RG register #define IL inline #define _ 1 ...

  5. 【LG2839】[国家集训队]middle

    [LG2839][国家集训队]middle 题面 洛谷 题解 按照求中位数的套路,我们二分答案\(mid\),将大于等于\(mid\)的数设为\(1\),否则为\(-1\). 若一个区间和大于等于\( ...

  6. BZOJ.2653.[国家集训队]middle(可持久化线段树 二分)

    BZOJ 洛谷 求中位数除了\(sort\)还有什么方法?二分一个数\(x\),把\(<x\)的数全设成\(-1\),\(\geq x\)的数设成\(1\),判断序列和是否非负. 对于询问\(( ...

  7. luogu2839 [国家集训队]middle

    题目链接:洛谷 题目大意:给定一个长度为$n$的序列,每次询问左端点在$[a,b]$,右端点在$[c,d]$的所有子区间的中位数的最大值.(强制在线) 这里的中位数定义为,对于一个长度为$n$的序列排 ...

  8. [洛谷P2839][国家集训队]middle

    题目大意:给你一个长度为$n$的序列$s$.$Q$个询问,问在$s$中的左端点在$[a,b]$之间,右端点在$[c,d]$之间的子段中,最大的中位数. 强制在线. 题解:区间中位数?二分答案,如果询问 ...

  9. Luogu 2839 [国家集训队]middle

    感觉这题挺好的. 首先对于中位数最大有一个很经典的处理方法就是二分,每次二分一个数组中的下标$mid$,然后我们把$mid$代回到原来的数组中检查,如果一个数$a_{i} \geq mid$,那么就把 ...

随机推荐

  1. 20155227《网络对抗》Exp7 网络欺诈防范

    20155227<网络对抗>Exp7 网络欺诈防范 实践内容(3.5分) 本实践的目标理解常用网络欺诈背后的原理,以提高防范意识,并提出具体防范方法.具体实践有 (1)简单应用SET工具建 ...

  2. 20155306 白皎 0day漏洞——基础知识

    20155306 白皎 0day漏洞--(第一篇)基础知识 写在前面: 本次免考实践方向是0day漏洞,以博客的形式记录了我的学习实践过程.第一篇博客主要围绕什么是0day漏洞以及一些以后学习中需要的 ...

  3. EZ 2018 03 23 NOIP2018 模拟赛(五)

    链接:http://211.140.156.254:2333/contest/65 这次Rating重回Rank18,我是20的守门员(滑稽) 这次题目和数据普遍偏水,我T2打错了一个变量名竟然过了所 ...

  4. AT24C02跨页写数据

    AT24C02 EEPROM的写数据分为:字节写数据模式和页写数据模式:字节写就是一个地址一个数据的写,页写是连续写数据,一个地址多个数据的写,但是页写不能自动跨页,如果超出一页长度,超出的数据会覆盖 ...

  5. python 回溯法 子集树模板 系列 —— 18、马踏棋盘

    问题 将马放到国际象棋的8*8棋盘board上的某个方格中,马按走棋规则进行移动,走遍棋盘上的64个方格,要求每个方格进入且只进入一次,找出一种可行的方案. 分析 说明:这个图是5*5的棋盘. 图片来 ...

  6. 用C++实现一个Brainfuck解释器

    Brainfuck是一种极小化的计算机语言,只含有8种运算符,由于fuck在英语中是脏话,这种语言有时被称为brainfck或brainf**,甚至被简称为BF.正如它的名字所暗示,brainfuck ...

  7. bodymovin实现将AE动画转换成HTML5动画

    做一个简单的记录,直接贴代码吧,主要还是设计师提供的那个json <!DOCTYPE html> <html> <head> <style> body ...

  8. 0.1 Maven相关知识(项目开发基础)

    一.Maven 1.1Maven是什么 Maven项目对象模型(POM),可以通过一小段描述信息来管理项目的构建,报告和文档的项目管理工具软件. Maven这个单词来自于意第绪语(犹太语),意为知识的 ...

  9. [2017BUAA软工助教]结对组队

    请同学们把第一次结对编程双方的学号评论在本博客下,只要一位同学评论即可.例如: 14061195 + 14061183

  10. GITHUB使用及入门总结

    这是我第一次应用git,以下仅供git的初学者参考.     github是一个基于git的代码托管平台,付费用户可以建私人仓库,我们一般的免费用户只能使用公共仓库,也就是代码要公开.这对于一般人来说 ...