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的4种文件类型Java,class,dex,apk
Java文件-----应用程序源文件 Android本身相当一部分都是用java编写而成(基本上架构图里头蓝色的部份都是用Java开发的),android的应用必须使用java来开发 Class文件- ...
- Android4.0-Fragment框架实现方式剖析(一)
1.什么是Fragment? Fragment包含在Activity中,Fragment只能存在于Activity的上下文(context)内,没有Activity就无 法使用Fragment,因此F ...
- CGGeometry Reference (一)
知识点 frame 与bounds 的区别 1.frame 是这个视图的大小在父视图的位置 . 如x 20 y 20 width 200 height 300 2.bounds 是这个视图的大小在自 ...
- jQuery $.each用法
以下内容非原创,来自百度文库http://wenku.baidu.com/view/4796b6145f0e7cd18425368e.html 好文要顶 关注我 收藏该文 mabel_on_lin ...
- Js经典相册
Js经典相册 点击下载
- 蓝灯github地址
https://github.com/getlantern/lantern/ 闪电联盟蓝灯: http://bbs.sdbeta.com/read-htm-tid-556664.html
- js 增删改查方法
push() 向数组的末尾添加一个或多个元素 pop() 删除数组内部并返回数组的最后一个元素 shift() 把数组内部的第一个元素从其中删除,并返回第一个元素的值 unshift() 向数组外部的 ...
- python执行linux shell管道输出内容
干净不留痕,用过都说好. echo "print 1+1" |python
- 探索Windows 8.1 Update 新功能点
Windows 8.1 Update 已经使用一段时间了,整体感觉比Windows 8.1 方便了不少,尤其是对鼠标用户来说更是进行了很多优化. 应用磁贴尺寸 在应用磁贴点击鼠标右键,有小.中.宽.大 ...
- rpc框架之 thrift 学习 1 - 安装 及 hello world
thrift是一个facebook开源的高效RPC框架,其主要特点是跨语言及二进制高效传输(当然,除了二进制,也支持json等常用序列化机制),官网地址:http://thrift.apache.or ...