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] (二分 + 主席树)的更多相关文章

  1. BZOJ2653 middle 【主席树】【二分】*

    BZOJ2653 middle Description 一个长度为n的序列a,设其排过序之后为b,其中位数定义为b[n/2],其中a,b从0开始标号,除法取下整.给你一个长度为n的序列s.回答Q个这样 ...

  2. BZOJ2653 middle 【二分 + 主席树】

    题目 一个长度为n的序列a,设其排过序之后为b,其中位数定义为b[n/2],其中a,b从0开始标号,除法取下整.给你一个 长度为n的序列s.回答Q个这样的询问:s的左端点在[a,b]之间,右端点在[c ...

  3. 【BZOJ2653】Middle(主席树)

    [BZOJ2653]Middle(主席树) 题面 BZOJ 洛谷 Description 一个长度为n的序列a,设其排过序之后为b,其中位数定义为b[n/2],其中a,b从0开始标号,除法取下整.给你 ...

  4. 洛谷P4559 [JSOI2018]列队 【70分二分 + 主席树】

    题目链接 洛谷P4559 题解 只会做\(70\)分的\(O(nlog^2n)\) 如果本来就在区间内的人是不用动的,区间右边的人往区间最右的那些空位跑,区间左边的人往区间最左的那些空位跑 找到这些空 ...

  5. 【BZOJ 4556】[Tjoi2016&Heoi2016]字符串 SAM+二分+主席树

    这道题市面上就两种法:一种是SA+二分+主席树,一种是SAM+二分+主席树(有不少人打线段树合并???)(除此之外还有一种利用炒鸡水的数据的暴力SA,贼快.....)(当时学SA的时候没做这道题,现在 ...

  6. 【BZOJ2653】middle(主席树,二分)

    题意:一个长度为n的序列a,设其排过序之后为b,其中位数定义为b[n/2],其中a,b从0开始标号,除法取下整. 给你一个长度为n的序列s. 回答Q个这样的询问:s的左端点在[a,b]之间,右端点在[ ...

  7. 【洛谷2839/BZOJ2653】middle(主席树)

    题目: 洛谷2839 分析: 记\(s_i\)表示原序列中第\(i\)大的数. 考虑对于任意一个区间\([a,b]\),设它的中位数为\(s_m\),那么这个区间内大于等于\(s_m\)的数和小于\( ...

  8. 「BZOJ 2653」middle「主席树」「二分」

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

  9. 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 ...

随机推荐

  1. C#/VB.NET Excel数据分列

    C#/VB.NET Excel数据分列 有时候我们需要将保存在Excel单元格中的组合型数据拆分为多列(如将全名拆分为姓和名两列)以方便我们处理.记忆或保存.为了避免重复和大量的手动输入工作,Exce ...

  2. Chrome调试中的奇技淫巧

    网上有关Chrome调试的文章一搜一大堆,本文主要记录一下自己平时经常用并且又比较冷门的一些技巧. 打开Chrome调试工具 1.打开控制台的情况下,长按页面的“刷新”按钮可以选择按何种方式刷新(有正 ...

  3. Http压测工具wrk使用指南

    用过了很多压测工具,却一直没找到中意的那款.最近试了wrk感觉不错,写下这份使用指南给自己备忘用,如果能帮到你,那也很好. 安装 wrk支持大多数类UNIX系统,不支持windows.需要操作系统支持 ...

  4. Linux内核启动过程概述

    版权声明:本文原创,转载需声明作者ID和原文链接地址. Hi!大家好,我是CrazyCatJack.今天给大家带来的是Linux内核启动过程概述.希望能够帮助大家更好的理解Linux内核的启动,并且创 ...

  5. 开源分布式数据库中间件MyCat源码分析系列

    MyCat是当下很火的开源分布式数据库中间件,特意花费了一些精力研究其实现方式与内部机制,在此针对某些较为重要的源码进行粗浅的分析,希望与感兴趣的朋友交流探讨. 本源码分析系列主要针对代码实现,配置. ...

  6. 理解浏览器历史记录(2)-hashchange、pushState

    本文也是一篇基础文章.继上文之后,本打算去研究pushState,偶然在一些信息中发现了锚点变化对浏览器的历史记录也会影响,同时锚点的变化跟pushState也有一些关联.所以就花了点时间,把这两个东 ...

  7. 在web浏览器上显示室内温度(nodeJs+arduino+socket.io)

    上次的nodejs操作arduino入门篇中实现了如何连接arduino.这次我们来实现通过arduino测量室内温度并在浏览器上显示出来. [所需材料] 硬件:LM35温度传感器,arduino u ...

  8. RedisRepository封装—Redis发布订阅以及StackExchange.Redis中的使用

    本文版权归博客园和作者本人吴双共同所有,转载请注明本Redis系列分享地址.http://www.cnblogs.com/tdws/tag/NoSql/ Redis Pub/Sub模式 基本介绍 Re ...

  9. Servlet 服务器性能提高--->数据库请求频率控制(原创)

    首先我要说下我实现这个功能接口涉及到的业务和实现的详细流程,然后会说此接口涉及到的相关技术,最后会贴出注释后的详细代码, 这个接口涉及到的是 app上咻一咻功能,咻一咻中奖的奖品一共有七类,其中四类是 ...

  10. 细谈Slick(6)- Projection:ProvenShape,强类型的Query结果类型

    在Slick官方文档中描述:连接后台数据库后,需要通过定义Projection,即def * 来进行具体库表列column的选择和排序.通过Projection我们可以选择库表中部分列.也可以增加一些 ...