bzoj2653: middle
首先,对于每个询问,我们二分答案
然后对于序列中大于等于中位数的数,我们把它们置为1,小于中位数的数,置为-1
那么如果一个区间和大于等于0,那么就资磁,否则就不滋磁
这个区间和呢,我们可以用主席树维护前缀和
[c,d]上的最大前缀和减去[a-1,b-1]上的最小前缀和,就是所有可用区间的最大区间和
这样要求主席树支持区间修改,正好之前没写过(捂脸),练一下
复杂度O(nlog^2n)
(如果不资磁区间修改的话,也可以通过维护最大/小连续和的那套理论,达到同样的效果(好像所有题解都是这么做的))
(当然首先要离散化……)
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#define N 23333 using namespace std;
inline int read(){
int ret=0;char ch=getchar();
while (ch<'0'||ch>'9') ch=getchar();
while ('0'<=ch&&ch<='9'){
ret=ret*10-48+ch;
ch=getchar();
}
return ret;
} struct STnode{
int ls,rs;
int maxv,minv;
int tag;
}; int n,root[N];
struct SegmentTree{
STnode t[12333666];
int size;
inline int newnode(int x){t[++size]=t[x];return size;}
void PushUp(int x){
t[x].maxv=max(t[t[x].ls].maxv,t[t[x].rs].maxv);
t[x].minv=min(t[t[x].ls].minv,t[t[x].rs].minv);
}
void add(int &x,int delta){
x=newnode(x);
t[x].maxv+=delta;t[x].minv+=delta;t[x].tag+=delta;
}
void PushDown(int x){
if (!t[x].ls) t[x].tag=0;
if (t[x].tag){
add(t[x].ls,t[x].tag);add(t[x].rs,t[x].tag);
t[x].tag=0;
}
}
void build(int x,int l,int r){
t[x].tag=t[x].ls=t[x].rs=0;
if ((t[x].minv=l)==(t[x].maxv=r)) return;
int mid=(l+r)/2;
build(t[x].ls=++size,l,mid);
build(t[x].rs=++size,mid+1,r);
}
int clear(){build(size=1,1,n);return 1;}
void modify(int &x,int L,int R,int l,int r,int delta){
PushDown(x);
if (l<=L&&R<=r){add(x,delta);return;}
x=newnode(x);
int mid=(L+R)/2;
if (l<=mid) modify(t[x].ls,L,mid,l,r,delta);
if (r>mid) modify(t[x].rs,mid+1,R,l,r,delta);
PushUp(x);
}
int qmin(int x,int L,int R,int l,int r){
PushDown(x);
if (l<=L&&R<=r) return t[x].minv;
int mid=(L+R)/2;
if (r<=mid) return qmin(t[x].ls,L,mid,l,r);
if (l>mid) return qmin(t[x].rs,mid+1,R,l,r);
return min(qmin(t[x].ls,L,mid,l,r),qmin(t[x].rs,mid+1,R,l,r));
}
int qmax(int x,int L,int R,int l,int r){
PushDown(x);
if (l<=L&&R<=r) return t[x].maxv;
int mid=(L+R)/2;
if (r<=mid) return qmax(t[x].ls,L,mid,l,r);
if (l>mid) return qmax(t[x].rs,mid+1,R,l,r);
return max(qmax(t[x].ls,L,mid,l,r),qmax(t[x].rs,mid+1,R,l,r));
}
} st; int query(int a,int b,int c,int d){
int l=1,r=n+1,mid;
while (l+1<r){
mid=(l+r)/2;
int tmpr=st.qmax(root[mid],1,n,c,d);
int tmpl=st.qmin(root[mid],1,n,max(a-1,1),b-1);
if (a==1) tmpl=min(tmpl,0);
if (tmpr-tmpl>=0) l=mid;
else r=mid;
}
return l;
} int a[N];
struct num{
int value,pos;
num(){}
num(int _value,int _pos):value(_value),pos(_pos){}
} tt[N];
inline bool operator <(const num &x,const num &y){
return x.value<y.value;
} int main(){
n=read();
for (int i=1;i<=n;++i) tt[i]=num(a[i]=read(),i);
sort(tt+1,tt+n+1); root[1]=st.clear();
for (int i=1;i<n;++i)
st.modify(root[i+1]=root[i],1,n,tt[i].pos,n,-2); int lastans=0,q[4];
for (int Q=read();Q;Q--){
for (int k=0;k<4;++k) q[k]=(read()+lastans)%n+1;
sort(q,q+4);
lastans=tt[query(q[0],q[1],q[2],q[3])].value;
printf("%d\n",lastans);
}
return 0;
}
bzoj2653: middle的更多相关文章
- BZOJ2653 middle 【主席树】【二分】*
BZOJ2653 middle Description 一个长度为n的序列a,设其排过序之后为b,其中位数定义为b[n/2],其中a,b从0开始标号,除法取下整.给你一个长度为n的序列s.回答Q个这样 ...
- BZOJ2653 middle(二分答案+主席树)
与中位数有关的题二分答案是很常用的trick.二分答案之后,将所有大于它的看成1小于它的看成-1,那么只需要判断是否存在满足要求的一段和不小于0. 由于每个位置是1还是-1并不固定,似乎不是很好算.考 ...
- [BZOJ2653]middle 主席树+二分
2653: middle Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 2042 Solved: 1123[Submit][Status][Disc ...
- [bzoj2653][middle] (二分 + 主席树)
Description 一个长度为n的序列a,设其排过序之后为b,其中位数定义为b[n/2],其中a,b从0开始标号,除法取下整. 给你一个长度为n的序列s. 回答Q个这样的询问:s的左端点在[a,b ...
- 题解【bzoj2653 middle】
Description 给你一个序列,每次询问给出四个数 \(a,b,c,d\),求所有区间 \([l,r]\) 满足 \(l \in [a,b], r \in [c,d]\) 的中位数的最大值.强制 ...
- BZOJ2653 middle 【二分 + 主席树】
题目 一个长度为n的序列a,设其排过序之后为b,其中位数定义为b[n/2],其中a,b从0开始标号,除法取下整.给你一个 长度为n的序列s.回答Q个这样的询问:s的左端点在[a,b]之间,右端点在[c ...
- PKUSC2018训练日程(4.18~5.30)
(总计:共66题) 4.18~4.25:19题 4.26~5.2:17题 5.3~5.9: 6题 5.10~5.16: 6题 5.17~5.23: 9题 5.24~5.30: 9题 4.18 [BZO ...
- 【BZOJ2653】Middle(主席树)
[BZOJ2653]Middle(主席树) 题面 BZOJ 洛谷 Description 一个长度为n的序列a,设其排过序之后为b,其中位数定义为b[n/2],其中a,b从0开始标号,除法取下整.给你 ...
- 【BZOJ2653】middle 二分+可持久化线段树
[BZOJ2653]middle Description 一个长度为n的序列a,设其排过序之后为b,其中位数定义为b[n/2],其中a,b从0开始标号,除法取下整.给你一个 长度为n的序列s.回答Q个 ...
随机推荐
- Android中一张图片加载后所占用内存大小的获取与测试
Android程序中一旦加载的图片比较多,就有可能出现Out of Memory而导致程序崩溃.这个一方面是因为Android系统本身对于每个单独的进程有内存大小的限制(有16M,64M,128M,2 ...
- 将pdf文件通过itunes直接拖到ipad的ibooks里面
开始不太清楚进行过什么设置,使得以前可以直接通过拖动的方式复制pdf文件到ipad里面的方法不管用了.在帖子http://bbs.weiphone.com/read-htm-tid-864091-pa ...
- angularjs之$timeout指令
angular.js的$timeout指令对window.setTimeout做了一个封装,它的返回值是一个promise对象.当定义的时间到了以后,这个promise对象就会被resolve,回调函 ...
- radio被选中,但是重复点击后事件不触发
网上找了好多帖子,都没用,在百度知道发现以下答案 知识点:使用 jq的prop才能设置 html $('.ss').click(function(){ $(this).find("input ...
- 使用gogs,drone搭建自动部署
使用gogs,drone搭建自动部署 使用gogs,drone,docker搭建自动部署测试环境 Gogs是一个使用go语言开发的自助git服务,支持所有平台Docker是使用go开发的开源容器引擎D ...
- 增强for循环(forearch)
增强for循环是为了简化在遍历数组需要先获得数组的长度或者在遍历集合中的元素的时候需要使用迭代器的操作. 引入时间:JDK1.5 语法格式: for(数据类型 变量 :需要迭代的数组或者集合){ } ...
- JavaEE PO VO BO DTO POJO DAO 整理总结
佩服能将复杂难懂的技术,抽象成简单易懂事物的人. 厌恶将简单易懂的技术,添加一堆专业术语将别人弄的头晕目眩的人. PO VO BO DTO POJO DAO 总体一览: 1.DAO[data acce ...
- Apache POI 实现对 Excel 文件读写
1. Apache POI 简介 Apache POI是Apache软件基金会的开放源码函式库. 提供API给Java应用程序对Microsoft Office格式档案读和写的功能. 老外起名字总是很 ...
- ajax请求过程中下载文件在火狐下的兼容问题
项目中碰到的问题,记录如下. 需求很简单,点击一个文件链接下载该文件,同时向后台发送请求.需求很常见,用户点击下载后通常要进行下载量的统计,统计的话可以利用 script标签 或者 img标签(图片p ...
- 完全开源Android网络框架 — 基于JAVA原生的HTTP框架
HttpNet网络请求框架基于HttpUrlConnection,采用Client + Request + Call的请求模型,支持https默认证书,数字安全证书.支持http代理!后续将会实现队列 ...