题面

求中位数的套路:二分,大于等于的设为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. 大数据入门第二十三天——SparkSQL(一)入门与使用

    一.概述 1.什么是sparkSQL 根据官网的解释: Spark SQL is a Spark module for structured data processing. 也就是说,sparkSQ ...

  2. 大数据入门第二十天——scala入门(二)scala基础01

    一.基础语法 1.变量类型 // 上表中列出的数据类型都是对象,也就是说scala没有java中的原生类型.在scala是可以对数字等基础类型调用方法的. 2.变量声明——能用val的尽量使用val! ...

  3. 20155206 Exp8 WEB基础实践

    20155206 Exp8 WEB基础实践 基础问题回答 (1)什么是表单 表单在网页中主要负责数据采集功能. 一个表单有三个基本组成部分: 表单标签:这里面包含了处理表单数据所用CGI程序的URL以 ...

  4. Android开发——监听Android手机的网络状态

    0. 前言 在Android开发中监听手机的网络状态是一个常见的功能,比如在没网的状态下进行提醒并引导用户打开网络设置,或者在非wifi状态下开启无图模式等等.因此本篇将网上的资料进行了整理总结,方便 ...

  5. 一、InnoDB引擎

    一.InnoDB的历史 MYSQL的5.1版本的时候还是使用旧的innoDB,当时orale公司推出的新的innoDB引擎, 但是需要以插件的形式编译,叫innoDB plugin : 知道MYSQL ...

  6. Codeforces 734E Anton and Tree(缩点+树的直径)

    题目链接: Anton and Tree 题意:给出一棵树由0和1构成,一次操作可以将树上一块相同的数字转换为另一个(0->1 , 1->0),求最少几次操作可以把这棵数转化为只有一个数字 ...

  7. Mybatis使用generator自动生成的Example类使用OR条件查询

    参考:https://blog.csdn.net/qq_36614559/article/details/80354511 public List<AssetsDevicetypeRefacto ...

  8. python编码你需要知道的编码风格

    此时你已经可以写一些更长更复杂的 Python 程序,是时候讨论一下 编码风格 了.大多数语言可以写(或者更明白的说, 格式化 )作几种不同的风格.有些比其它的更好读.让你的代码对别人更易读是个好想法 ...

  9. Java使用Redis学习笔记

    如果我们使用Java操作Redis, 需要确保已经安装了 redis 服务及 Java redis 驱动. Maven项目可以直接在pom.xml中加入jedis包驱动: <dependency ...

  10. aiohttp基本及进阶使用

    客户端使用 发起请求 让我们从导入aiohttp模块开始: import aiohttp 好啦,我们来尝试获取一个web页面.比如我们来获取下GitHub的时间轴. async with aiohtt ...