[bzoj2653][middle] (二分 + 主席树)
Description
一个长度为n的序列a,设其排过序之后为b,其中位数定义为b[n/2],其中a,b从0开始标号,除法取下整。
给你一个长度为n的序列s。
回答Q个这样的询问:s的左端点在[a,b]之间,右端点在[c,d]之间的子序列中,最大的中位数。
其中a<b<c<d。
位置也从0开始标号。
我会使用一些方式强制你在线。
Input
第一行序列长度n。
接下来n行按顺序给出a中的数。
接下来一行Q。
然后Q行每行a,b,c,d,我们令上个询问的答案是x(如果这是第一个询问则x=0)。
令数组q={(a+x)%n,(b+x)%n,(c+x)%n,(d+x)%n}。
将q从小到大排序之后,令真正的要询问的a=q[0],b=q[1],c=q[2],d=q[3]。
输入保证满足条件。
Output
Q行依次给出询问的答案。
Sample Input
Sample Output
HINT
0:n,Q<=100
1,...,5:n<=2000
0,...,19:n<=20000,Q<=25000
Solution
一道神奇的题目,在长沙培训时初次见面
和一般主席树的做法不尽相同
为了避免枚举中位数,我们将序列排序,对排序后的点建立一颗以整个序列编号为节点的线段树
此后,对于每个有序点的线段树,我们将其内的所有值小于它的点的贡献标记为-1,记录从左边起最大连续和,还有从右边起最大连续和
显然,这个排序后的主席树是满足二分性质的
那么,我们二分中位数,查询区间[B,C]的贡献、[A,B)的右边最大连续和、(C,D]的左边最大连续和是否大于或等于0,若是,则说明它可以构成一个合法的中位数是当前二分值的序列,也说明中位数大于或等于当前此数
最后输出二分答案即可
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 20200
#define mid ((s) + (t) >> (1))
#define dmax(a, b) ((a) > (b) ? (a) : (b)) using namespace std; inline int Rin(){
int x = , c = getchar(), f = ;
for(; c < || c > ; c = getchar())
if(!(c ^ ))f = -;
for(; c > && c < ; c = getchar())
x = (x << ) + (x << ) + c - ;
return x * f;
} int n; namespace Arcueid{
struct Area{
int lq, rq, sum; Area(int x = ){
lq = rq = dmax(x, );
sum = x;
}
}; Area operator + (Area a, Area b){
Area c;
c.sum = a.sum + b.sum;
c.lq = dmax(a.lq, a.sum + b.lq);
c.rq = dmax(b.rq, a.rq + b.sum);
return c;
} struct Node{
Node *l, *r;
Area key;
Node(){}
Node(Node *_l, Node *_r, Area _key) : l(_l), r(_r), key(_key) {}
}*_nil = new Node(), *nil = (*_nil = Node(_nil, _nil, ), _nil), pool[N * ], *top = pool, *rt[N];
Node *newnode(Node *_, Node *__, Area ___){
*top = Node(_, __, ___);
return top++;
} Node *born(int s, int t){
if(!(s ^ t))return newnode(0x0, 0x0, Area());
Node *_ = born(s, mid); Node *__ = born(mid + , t);
return newnode(_, __, _->key + __->key);
} Node *real(Node *p, int s, int t, int k){
if(!(s ^ t))return newnode(0x0, 0x0, Area(-));
if(k <= mid){
Node *_ = real(p->l, s, mid, k);
return newnode(_, p->r, _->key + p->r->key);
}
else{
Node *_ = real(p->r, mid + , t, k);
return newnode(p->l, _, p->l->key + _->key);
}
} Area secret(Node *p, int s, int t, int l, int r){
if(l == s && t == r)return p->key;
if(r <= mid)return secret(p->l, s, mid, l, r);
if(l > mid)return secret(p->r, mid + , t, l, r);
return secret(p->l, s, mid, l, mid) + secret(p->r, mid + , t, mid + , r);
} bool judge(int A, int B, int C, int D, int k){
int res = ;
res += secret(rt[k], , n, B, C).sum;
res += secret(rt[k], , n, A, B - ).rq;
res += secret(rt[k], , n, C + , D).lq;
return res >= ;
} int binsearch(int A, int B, int C, int D){
int s = , t = n;
while(s + < t){
if(judge(A, B, C, D, mid))
s = mid;
else
t = mid;
}
if(judge(A, B, C, D, t))
return t;
return s;
}
} namespace moon{
struct dat{
int key, pos; void init(int _) {key = Rin(); pos = _;} bool operator < (const dat h)const{
return key < h.key;
}
}b[N]; void cause(){
n = Rin();
for(int i = ; i <= n; i++)
b[i].init(i);
sort(b + , b + + n);
Arcueid::rt[] = Arcueid::born(, n);
for(int i = ; i <= n; i++)
Arcueid::rt[i] = Arcueid::real(Arcueid::rt[i - ], , n, b[i - ].pos);
int m = Rin(), ans = , q[];
while(m--){
for(int j=;j<;j++)
q[j] = Rin(), q[j] = (q[j] + ans) % n+;
sort(q,q+);
printf("%d\n", ans = b[Arcueid::binsearch(q[],q[],q[],q[])].key);
}
}
} int main(){
moon::cause();
return ;
}
[bzoj2653][middle] (二分 + 主席树)的更多相关文章
- BZOJ2653 middle 【主席树】【二分】*
BZOJ2653 middle Description 一个长度为n的序列a,设其排过序之后为b,其中位数定义为b[n/2],其中a,b从0开始标号,除法取下整.给你一个长度为n的序列s.回答Q个这样 ...
- BZOJ2653 middle 【二分 + 主席树】
题目 一个长度为n的序列a,设其排过序之后为b,其中位数定义为b[n/2],其中a,b从0开始标号,除法取下整.给你一个 长度为n的序列s.回答Q个这样的询问:s的左端点在[a,b]之间,右端点在[c ...
- 【BZOJ2653】Middle(主席树)
[BZOJ2653]Middle(主席树) 题面 BZOJ 洛谷 Description 一个长度为n的序列a,设其排过序之后为b,其中位数定义为b[n/2],其中a,b从0开始标号,除法取下整.给你 ...
- 洛谷P4559 [JSOI2018]列队 【70分二分 + 主席树】
题目链接 洛谷P4559 题解 只会做\(70\)分的\(O(nlog^2n)\) 如果本来就在区间内的人是不用动的,区间右边的人往区间最右的那些空位跑,区间左边的人往区间最左的那些空位跑 找到这些空 ...
- 【BZOJ 4556】[Tjoi2016&Heoi2016]字符串 SAM+二分+主席树
这道题市面上就两种法:一种是SA+二分+主席树,一种是SAM+二分+主席树(有不少人打线段树合并???)(除此之外还有一种利用炒鸡水的数据的暴力SA,贼快.....)(当时学SA的时候没做这道题,现在 ...
- 【BZOJ2653】middle(主席树,二分)
题意:一个长度为n的序列a,设其排过序之后为b,其中位数定义为b[n/2],其中a,b从0开始标号,除法取下整. 给你一个长度为n的序列s. 回答Q个这样的询问:s的左端点在[a,b]之间,右端点在[ ...
- 【洛谷2839/BZOJ2653】middle(主席树)
题目: 洛谷2839 分析: 记\(s_i\)表示原序列中第\(i\)大的数. 考虑对于任意一个区间\([a,b]\),设它的中位数为\(s_m\),那么这个区间内大于等于\(s_m\)的数和小于\( ...
- 「BZOJ 2653」middle「主席树」「二分」
题意 一个长度为\(n\)的序列\(a\),设其排过序之后为\(b\),其中位数定义为\(b[n/2]\),其中\(a,b\)从\(0\)开始标号,除法取下整.给你一个长度为\(n\)的序列\(s\) ...
- Codeforces Round #276 (Div. 1) E. Sign on Fence 二分+主席树
E. Sign on Fence Bizon the Champion has recently finished painting his wood fence. The fence consi ...
随机推荐
- .net erp(办公oa)开发平台架构之流程服务概要介绍
背景 搭建一个适合公司erp业务的开发平台. 架构概要图: 流程引擎开发平台: 包含流程引擎设计器,流程管理平台,流程引擎服务.目前只使用单个数据库进行管理. 流程引擎设计器 采用silve ...
- SQL Tuning 基础概述08 - SQL Tuning Advisor
SQL调优顾问 SQL Tuning Advisor的使用案例: 1.构建测试表T 2.定义调整任务 3.修改调整任务参数 4.执行调整任务 5.监控调整任务 6.查看调整任务建议 7.删除调整任务 ...
- HTML5-video标签-实现点击预览图播放或暂停视频
HTML5-video标签-实现点击预览图播放或暂停视频 刚刚参加工作,开始更多的接触到一些新的知识,促使我开始了解html5和css3的新特性.这时我才真的发现到html5和css3的强大. 之前关 ...
- Aspose.Words简单生成word文档
Aspose.Words简单生成word文档 Aspose.Words.Document doc = new Aspose.Words.Document(); Aspose.Words.Documen ...
- asp.net MVC4——省市三级联动数据库
数据库设计
- 来玩Play框架01 简介
作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 说到网络框架,Ruby的Ruby on Rail和Python的Django都相当 ...
- 如何写出安全的API接口(参数加密+超时处理+私钥验证+Https)- 续(附demo)
上篇文章说到接口安全的设计思路,如果没有看到上篇博客,建议看完再来看这个. 通过园友们的讨论,以及我自己查了些资料,然后对接口安全做一个相对完善的总结,承诺给大家写个demo,今天一并放出. 对于安全 ...
- 用C#从数据库动态生成AdminLTE菜单的一种方法
当前的应用设计风格趋于Flat扁平化,很多基于BootStrap实现了很多UI非常漂亮的管理界面(Bootstrap admin template). 此核心文件开源在Github:https://g ...
- RESTful Api 身份认证安全性设计
REST是一种软件架构风格.RESTful Api 是基于 HTTP 协议的 Api,是无状态传输.它的核心是将所有的 Api 都理解为一个网络资源.将所有的客户端和服务器的状态转移(动作)封装到 H ...
- AlloyRenderingEngine继承
写在前面 不读文章,只对代码感兴趣可以直接跳转到这里 https://github.com/AlloyTeam/AlloyGameEngine然后star一下,多谢支持:). 前几天发了篇向ES6靠齐 ...