博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[bzoj2653]middle
阅读量:4327 次
发布时间:2019-06-06

本文共 3026 字,大约阅读时间需要 10 分钟。

来自FallDream的博客,未经允许,请勿转载,谢谢


ditoly太强了 随便切  我被d飞了

-------------------------------

由n个数ai,每次询问,给定四个数a,b,c,d,求一个左端点在[a,b],右端点在[c,d]的子序列(原题这么写,但是实际上是子串),使得它的中位数最大。强制在线

n<=20000 q<=25000

题解:考虑二分一个答案,然后check一下是否能够取到。

怎么check呢?假设要check一个数X,那么我们把大等于X的数字看成1,小于的看成-1,如果存在一个子序列的和大等于0,那么这个数字就是合法的。

所以我们可以维护一棵线段树,直接把每一位看成1或者-1,维护前缀和数组的最大最小值,然后数字从小到大把线段树可持久化一下,每次一个数字从1变成-1就是把一段区间-2,这个我们通过标记永久化实现。

复杂度$qlog^{2}n$

#include
#include
#include
#define MN 20000#define pa pair
#define mp(x,y) make_pair(x,y)#define INF 2000000000using 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 * 10 + ch - '0';ch = getchar();} return x * f;}int n,m,last=0,num[10],a[MN+5],cnt=0,l[MN+5],rt[MN+5];pa p[MN+5];struct data{ int mx,mn; data(int x=0):mx(x),mn(x){} data(int x,int y):mx(x),mn(y){} data operator*(const data&b){
return data(max(mx,b.mx),min(mn,b.mn));} data operator+(int y){
return data(mx+y,mn+y);}};struct node{
int l,r,val;data x;}T[MN*60+5];inline int mark(int x,int k){ int nx=++cnt;T[nx].l=T[x].l;T[nx].r=T[x].r; T[nx].x=T[x].x+k;T[nx].val=T[x].val+k; return nx;}void pushdown(int x){ T[x].l=mark(T[x].l,T[x].val); T[x].r=mark(T[x].r,T[x].val); T[x].val=0;}int ins(int x,int l,int r,int ad,int lt=0,int rt=n){ if(l==lt&&rt==r){
return mark(x,ad);} int nx=mark(x,0);pushdown(nx); int mid=lt+rt>>1; if(r<=mid) T[nx].l=ins(T[nx].l,l,r,ad,lt,mid); else if(l>mid) T[nx].r=ins(T[nx].r,l,r,ad,mid+1,rt); else T[nx].l=ins(T[nx].l,l,mid,ad,lt,mid),T[nx].r=ins(T[nx].r,mid+1,r,ad,mid+1,rt); T[nx].x=T[T[nx].l].x*T[T[nx].r].x; return nx;}int build(int l,int r){ int x=++cnt,mid=l+r>>1; if(l==r) {T[x].x=data(l);return x;} T[x].l=build(l,mid);T[x].r=build(mid+1,r); T[x].x=T[T[x].l].x*T[T[x].r].x; return x;}data query(int x,int l,int r,int lt=0,int rt=n){ if(l==lt&&rt==r) return T[x].x; int mid=lt+rt>>1; if(r<=mid) return query(T[x].l,l,r,lt,mid)+T[x].val; else if(l>mid) return query(T[x].r,l,r,mid+1,rt)+T[x].val; else return query(T[x].l,l,mid,lt,mid)*query(T[x].r,mid+1,r,mid+1,rt)+T[x].val;}int main(){ n=read(); for(int i=1;i<=n;i++) a[i]=read(); for(int i=1;i<=n;i++) p[i]=mp(a[i],i); sort(p+1,p+n+1);rt[1]=build(0,n); for(int i=2;i<=n;i++) rt[i]=ins(rt[i-1],p[i-1].second,n,-2); m=read(); for(int i=1;i<=m;i++) { for(int j=1;j<=4;j++) num[j]=(read()+last)%n+1; sort(num+1,num+5); int a=num[1],b=num[2],c=num[3],d=num[4]; int L=1,R=n,mid,ans=0; while(L<=R) { mid=L+R>>1; if(query(rt[mid],c,d).mx-query(rt[mid],a-1,b-1).mn>=0) ans=mid,L=mid+1; else R=mid-1; } printf("%d\n",last=p[ans].first); } return 0;}

 

转载于:https://www.cnblogs.com/FallDream/p/bzoj2653.html

你可能感兴趣的文章
阶段3 2.Spring_02.程序间耦合_1 编写jdbc的工程代码用于分析程序的耦合
查看>>
阶段3 2.Spring_01.Spring框架简介_04.spring发展历程
查看>>
阶段3 2.Spring_02.程序间耦合_3 程序的耦合和解耦的思路分析1
查看>>
阶段3 2.Spring_02.程序间耦合_5 编写工厂类和配置文件
查看>>
阶段3 2.Spring_01.Spring框架简介_05.spring的优势
查看>>
阶段3 2.Spring_02.程序间耦合_7 分析工厂模式中的问题并改造
查看>>
阶段3 2.Spring_02.程序间耦合_4 曾经代码中的问题分析
查看>>
阶段3 2.Spring_03.Spring的 IOC 和 DI_2 spring中的Ioc前期准备
查看>>
阶段3 2.Spring_03.Spring的 IOC 和 DI_4 ApplicationContext的三个实现类
查看>>
阶段3 2.Spring_02.程序间耦合_8 工厂模式解耦的升级版
查看>>
阶段3 2.Spring_03.Spring的 IOC 和 DI_6 spring中bean的细节之三种创建Bean对象的方式
查看>>
阶段3 2.Spring_04.Spring的常用注解_3 用于创建的Component注解
查看>>
阶段3 2.Spring_04.Spring的常用注解_2 常用IOC注解按照作用分类
查看>>
阶段3 2.Spring_09.JdbcTemplate的基本使用_5 JdbcTemplate在spring的ioc中使用
查看>>
阶段3 3.SpringMVC·_07.SSM整合案例_02.ssm整合之搭建环境
查看>>
小D课堂 - 零基础入门SpringBoot2.X到实战_第1节零基础快速入门SpringBoot2.0_3、快速创建SpringBoot应用之手工创建web应用...
查看>>
阶段3 3.SpringMVC·_07.SSM整合案例_04.ssm整合之编写SpringMVC框架
查看>>
小D课堂 - 零基础入门SpringBoot2.X到实战_第1节零基础快速入门SpringBoot2.0_5、SpringBoot2.x的依赖默认Maven版本...
查看>>
阶段3 3.SpringMVC·_07.SSM整合案例_08.ssm整合之Spring整合MyBatis框架
查看>>
小D课堂 - 零基础入门SpringBoot2.X到实战_第2节 SpringBoot接口Http协议开发实战_9、SpringBoot基础HTTP其他提交方法请求实战...
查看>>