传送门

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!

转载于:https://www.cnblogs.com/PaperCloud/p/10273093.html

[bzoj 2653][国家集训队]middle相关推荐

  1. P2839 [国家集训队]middle(二分 套 主席树)

    P2839 [国家集训队]middle 有一个长度为nnn的序列,有mmm次询问,每次询问a,b,c,da, b, c, da,b,c,d,为l∈[a,b],r∈[c,d]l \in [a, b], ...

  2. 洛谷P2839 [国家集训队]middle(主席树)

    P2839 [国家集训队]middle 我们可以考虑二分中位数 checkcheckcheck 答案,那么我们对于某个值 midmidmid ,把 [l,r][l,r][l,r] 内的所有小于 mid ...

  3. BZOJ 2154 [国家集训队]Crash的数字表格 / JZPTAB(莫比乌斯反演,经典好题)(Luogu P1829)

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 P1829 [国家集训队]Crash的数字表格 / JZPTAB(反演,经典好题) Problem S ...

  4. bzoj 2653 洛谷 P2839 [国家集训队] middle

    2653: middle Time Limit: 20 Sec  Memory Limit: 512 MB Submit: 2381  Solved: 1340 [Submit][Status][Di ...

  5. 可持久化普通线段树 ---- P2839 [国家集训队]middle 可持久化普通线段树 + 二分 求中位数最大值

    题目链接 题目大意: 解题思路: 这个题思路很妙!! 首先我们假设只有一次询问怎么做? 那么我们可以二分出这个最大值midmidmid,然后把大于等于midmidmid设置成111,把小于midmid ...

  6. luogu2839 [国家集训队]middle

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

  7. P2839 [国家集训队]middle

    题面 • 提一下静态区间第k小的nlog2n的做法: 1. 建关于排名的主席树(按排名顺序建树). 2. 二分答案. • 这样做静态区间第k小的虽然有些ZZ,但它的意义在于将线段树   维护的对象改变 ...

  8. P2839 [国家集训队]middle 二分 + 主席树 在值域上建区间

    传送门 文章目录 题意: 思路: 题意: 思路: 我们先解决怎么判断中位数的问题,我们可以二分一个midmidmid,将<mid<mid<mid的值都变成−1-1−1,其他的数都变成 ...

  9. [国家集训队]middle(二分+主席树[中位数思维题])

    文章目录 点击查看 solution code 点击查看 solution 简单口胡一下就跑 考虑二分答案ansansans 区间[x1,x2],x1∈[a,b],x2∈[c,d][x1,x2],x1 ...

最新文章

  1. qoq是什么意思的缩写_“yjgj他的pyq很zqsg”,90后从未觉得自己老,直到看到00后缩写的那一秒……...
  2. 想用Python爬小姐姐图片?那你得先搞定分布式进程
  3. 快递员遭投诉吞安眠药护自尊 顺丰王卫:马上检讨 立即整改
  4. 照片快照清除 android,如何在Android中删除和恢复照片
  5. 电动车爬坡时究竟应该用最快档还是用最慢档?
  6. java-线程-使用阻塞队列(BlockingQueue)控制线程通信
  7. AI进军华尔街!《终极算法》作者Domingos加盟对冲基金巨头
  8. 韩顺平 零基础30天学会Java 笔记(一)
  9. nodejs如何运行JavaScript代码
  10. 解惑:Redis的HSCAN命令中COUNT参数的失效场景
  11. Anaconda出现Navigator Error的解决办法
  12. 2021-10-25
  13. Java获取某年某月的第一天
  14. windows性能监视器API
  15. 转录组RNA-seq分析前沿进展综述
  16. 小白入门——关于什么是区块链
  17. [学习]18 SMART原则 如何科学的制定计划
  18. WebProxy - 网站转发代理
  19. elementui select选中获取整个item对象以及回显
  20. 一文理解所有需求分析中的基本术语

热门文章

  1. 2019\Province_C_C++_B\试题C-数列求值
  2. LeetCode Algorithm 7. 整数反转
  3. 征战蓝桥 —— 2014年第五届 —— C/C++A组第5题——锦标赛
  4. 【STM32】 keil软件介绍--工程目标选项配置(上)
  5. python 类属性排序_Python实现多属性排序的方法
  6. 闪烁点击效果css,CSS3自定义闪烁动画效果实例
  7. 数据库原理学习笔记(二)数据库范式
  8. 解决 Xcode10 编译错误 ld: library not found for -lstdc++6.0.9
  9. BackTrack5 安装中文输入法
  10. c++成员运算符的重载