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

本文共 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

你可能感兴趣的文章
设计模式 - 代理模式(Proxy Pattern)
查看>>
mybatis-generator配置文件详解
查看>>
关于浏览器显示不出js的问题
查看>>
获取文件md5命令
查看>>
机器学习十大经典算法
查看>>
Vultr centost7一键安装BBR工具教程
查看>>
connect mysql
查看>>
SQL慢查询测试实践
查看>>
UWP开发砸手机系列(一)—— Accessibility
查看>>
javascript中的对象转数组的方法
查看>>
python小白-day8 socketserver模块
查看>>
HDU3560 Graph’s Cycle Component 图论基础题
查看>>
自我介绍
查看>>
我的第一个reactnative
查看>>
SpringCloud学习笔记《---02 Eureka ---》篇
查看>>
机器学习/深度学习/其他开发环境搭建记录
查看>>
xml.exist() 实例演示
查看>>
判断是否为空然后赋值
查看>>
中标麒麟QT+ODBC+人大金仓开发环境配置
查看>>
Silverlight WCF RIA服务(九)Domain Service 2
查看>>