传送门

Description

一个长度为\(n\)的序列\(a\),设其排过序之后为\(b\),其中位数定义为\(b[n/2]\),其中\(a,b\)从\(0\)开始标号,除法取下整。

给你一个长度为n的序列\(s\)。

回答\(Q\)个这样的询问:\(s\)的左端点在\([a,b]\)之间,右端点在\([c,d]\)之间的子序列中,最大的中位数。

其中\(a<b<c<d\)。

位置也从\(0\)开始标号,强制在线

Solution

求中位数有一个很常见的做法,二分一个答案,把大于等于它的数设为\(1\),小于它的数设为\(1\)

这样,如果区间和大于等于\(0\),中位数显然会大于等于当前答案

可以对每个权值都建一个线段树,当然可以用主席树来实现

check的时候,我们显然需要得到区间最大值,对\([a,b]\)求后缀最大值,\([b+1,c-1]\)区间求和,\([c,d]\)求前缀最大值即可

调了很久,一直都是\(95\)分,结果是id[i-1].size-1写成了id[i-1].size,我倒了

Code 

#include<bits/stdc++.h>
#define ll long long
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
using namespace std;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
return x*f;
}
#define MN 20005
int n,N,val[MN],nn[MN],root[MN];
std::vector<int> id[MN];
struct Node{int ls,rs,lm,rm,s;}t[MN*50];int sz;
#define mid ((l+r)>>1)
#define lson t[x].ls
#define rson t[x].rs
inline void up(int x)
{
t[x].s=t[lson].s+t[rson].s;
t[x].rm=max(t[rson].rm,t[lson].rm+t[rson].s);
t[x].lm=max(t[lson].lm,t[rson].lm+t[lson].s);
}
inline void Build(int &x,int l,int r)
{
x=++sz;if(l==r) return (void)(t[x]=(Node){0,0,1,1,1});
Build(lson,l,mid);Build(rson,mid+1,r);up(x);
}
inline void Modify(int &x,int l,int r,int p)
{
t[++sz]=t[x];x=sz;
if(l==r){t[x].s=t[x].lm=t[x].rm=-1;return;}
p<=mid?Modify(lson,l,mid,p):Modify(rson,mid+1,r,p);up(x);
}
#define P std::pair<int,int>
inline P QR(int x,int l,int r,int a,int b)
{
if(a==l&&r==b) return std::make_pair(t[x].rm,t[x].s);
if(b<=mid) return QR(lson,l,mid,a,b);
if(a>mid) return QR(rson,mid+1,r,a,b);
P L=QR(lson,l,mid,a,mid),R=QR(rson,mid+1,r,mid+1,b);
return std::make_pair(max(L.first+R.second,R.first),L.second+R.second);
}
inline P QL(int x,int l,int r,int a,int b)
{
if(a==l&&r==b) return std::make_pair(t[x].lm,t[x].s);
if(b<=mid) return QL(lson,l,mid,a,b);
if(a>mid) return QL(rson,mid+1,r,a,b);
P L=QL(lson,l,mid,a,mid),R=QL(rson,mid+1,r,mid+1,b);
return std::make_pair(max(R.first+L.second,L.first),L.second+R.second);
}
inline int QS(int x,int l,int r,int a,int b)
{
if(a>b) return 0;
if(a==l&&r==b) return t[x].s;
if(b<=mid) return QS(lson,l,mid,a,b);
if(a>mid) return QS(rson,mid+1,r,a,b);
return QS(lson,l,mid,a,mid)+QS(rson,mid+1,r,mid+1,b);
}
inline bool check(int a,int b,int c,int d,int v)
{
int Ans=QR(root[v],1,n,a,b).first+QS(root[v],1,n,b+1,c-1)+QL(root[v],1,n,c,d).first;
return Ans>=0;
}
int main()
{
n=read();register int i,j;
for(i=1;i<=n;++i) nn[i]=val[i]=read();
std::sort(nn+1,nn+n+1);N=std::unique(nn+1,nn+n+1)-nn-1;
for(i=1;i<=n;++i) val[i]=std::lower_bound(nn+1,nn+N+1,val[i])-nn,id[val[i]].push_back(i);
Build(root[1],1,n);
for(i=2;i<=N;++i)
{
root[i]=root[i-1];
for(j=id[i-1].size()-1;~j;--j) Modify(root[i],1,n,id[i-1][j]);
}
register int Q=read(),a[6],x=0,l,r;
while(Q--)
{
for(i=0;i<4;++i) a[i]=(read()+x)%n+1;
std::sort(a,a+4);
for(x=l=1,r=N;l<=r;check(a[0],a[1],a[2],a[3],mid)?(x=mid,l=mid+1):r=mid-1);
printf("%d\n",x=nn[x]);
}
return 0;
}

Blog来自PaperCloud,未经允许,请勿转载,TKS!

[bzoj 2653][国家集训队]middle的更多相关文章

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

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

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

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

  3. [国家集训队]middle

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

  4. P2839 [国家集训队]middle

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

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

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

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

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

  7. BZOJ.2565.[国家集训队]最长双回文串(Manacher/回文树)

    BZOJ 洛谷 求给定串的最长双回文串. \(n\leq10^5\). Manacher: 记\(R_i\)表示以\(i\)位置为结尾的最长回文串长度,\(L_i\)表示以\(i\)开头的最长回文串长 ...

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

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

  9. BZOJ 2631 [国家集训队]Tree II (LCT)

    题目大意:给你一棵树,让你维护一个数据结构,支持 边的断,连 树链上所有点点权加上某个值 树链上所有点点权乘上某个值 求树链所有点点权和 (辣鸡bzoj又是土豪题,洛谷P1501传送门) LCT裸题, ...

随机推荐

  1. 在论坛中出现的比较难的sql问题:34(递归 获取连续值问题)

    原文:在论坛中出现的比较难的sql问题:34(递归 获取连续值问题) 所以,觉得有必要记录下来,这样以后再次碰到这类问题,也能从中获取解答的思路.

  2. linux 基础指令

    df -h 查看磁盘空间 root@ubuntu:/etc# df -h Filesystem Size Used Avail Use% Mounted on udev 970M 0 970M 0% ...

  3. github新建远程仓库初始化记录

    …or create a new repository on the command line echo "# 输出内容" >> README.md git init ...

  4. 制作win10系统及安装win10系统

    制作win10系统 1.登陆msdn,下载win10系统,打开迅雷下载器,复制完该段代码,直接开始下载,网址:https://msdn.itellyou.cn/ 2.下载软碟通,下载网址:https: ...

  5. L ==> E · L · K

    三剑客:Elastic Stack 在学习ELK前,先对 Lucene作基本了解. 今天才知道关系型数据库的索引是 B-Tree,罪过... 减少磁盘寻道次数 ---> 提高查询性能 Lucen ...

  6. jenkins+docker+git+harbor构建及代码回滚(未完)

    目录 一.部署 环境工作流程介绍 部署harbor 一.部署 前提环境说明 192.168.111.3 该机器为git本地仓库,及git远程仓库(git用户创建),及Harbor镜像仓库 192.16 ...

  7. Django中使用geetest验证

    一.geetest的使用方法 首先需要在setting中配置好文件 GEE_TEST = { "gee_test_access_id": "37ca5631edd1e88 ...

  8. nginx的应用【虚拟主机】

    Nginx主要应用: 静态web服务器 负载均衡 静态代理虚拟主机 虚拟主机 :虚拟主机,就是把一台物理服务器划分成多个“虚拟”的服务器,这样我们的一台物理服务器就可以当做多个服务器来使用,从而可以配 ...

  9. 刷题小tips

    自从认真做题以后,结合自己的做题体验以及网上前人的总结经验贴,罗列下列的小建议: 1.为了避免每一次都要重复输入测试数据的麻烦,利用输入重定向文件 我是只把标准输入stdin重定位到in.txt,然后 ...

  10. 5.Kafka消费者-从Kafka读取数据(转)

    http://www.dengshenyu.com/%E5%88%86%E5%B8%83%E5%BC%8F%E7%B3%BB%E7%BB%9F/2017/11/14/kafka-consumer.ht ...