博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
BZOJ 4552(二分+线段树+思维)
阅读量:5366 次
发布时间:2019-06-15

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

题面

分析

此题是道好题!

首先要跳出思维定势,不是去想如何用数据结构去直接维护排序过程,而是尝试二分a[p]的值
设二分a[p]的值为x
我们将大于x的数标记为1,小于等于x的数标记为0
则整个序列只由01组成,记为b
将一个区间升序排序,则相当于将1全部移到右边,0全部移到左边,降序排序反之
例:
a={1,6,5,2,4,3}.x=4
标记后的序列b为{0,1,1,0,0,0}
此时对[1,5]进行升序排序,a={1,2,4,5,6,3}
标记后的序列b为{0,0,0,1,1,0}

因此可以用线段树维护标记后的序列,直接区间求和得到1的个数,再区间更新即可

如果排完序后b[p]=0,则说明a[p]<=x,继续减小x
否则增大x

代码

#include
#include
#include
#include
#define maxn 100005using namespace std;int n,m,qa;struct node { int l; int r; int v; int mark; int len() { return r-l+1; }} tree[maxn<<2];int a[maxn];struct sort_seg { int l; int r; int type;} q[maxn];void push_up(int pos) { tree[pos].v=tree[pos<<1].v+tree[pos<<1|1].v;}void build(int l,int r,int pos,int middle) { tree[pos].l=l; tree[pos].r=r; tree[pos].v=0; tree[pos].mark=-1; if(l==r) { tree[pos].v=(a[l]>middle); return; } int mid=(tree[pos].l+tree[pos].r)>>1; build(l,mid,pos<<1,middle); build(mid+1,r,pos<<1|1, middle); push_up(pos);}void push_down(int pos) { if(tree[pos].mark!=-1) { tree[pos<<1].mark=tree[pos].mark; tree[pos<<1|1].mark=tree[pos].mark; tree[pos<<1].v=tree[pos].mark*tree[pos<<1].len(); tree[pos<<1|1].v=tree[pos].mark*tree[pos<<1|1].len(); tree[pos].mark=-1; }}void update(int L,int R,int v,int pos) { if(R
tree[pos].r) return; if(L<=tree[pos].l&&R>=tree[pos].r) { tree[pos].v=v*tree[pos].len(); tree[pos].mark=v; return; } push_down(pos); int mid=(tree[pos].l+tree[pos].r)>>1; if(L<=mid) update(L,R,v,pos<<1); if(R>mid) update(L,R,v,pos<<1|1); push_up(pos);}int query(int L,int R,int pos) { if(R
tree[pos].r) return 0; if(L<=tree[pos].l&&R>=tree[pos].r) { return tree[pos].v; } push_down(pos); int mid=(tree[pos].l+tree[pos].r)>>1; int ans=0; if(L<=mid) ans+=query(L,R,pos<<1); if(R>mid) ans+=query(L,R,pos<<1|1); return ans;}int check(int x) { build(1,n,1,x); for(int i=1; i<=m; i++) { int sum=query(q[i].l,q[i].r,1); if(q[i].type==0) { update(q[i].l,q[i].r-sum,0,1); update(q[i].r-sum+1,q[i].r,1,1); } else { update(q[i].l,q[i].l+sum-1,1,1); update(q[i].l+sum,q[i].r,0,1); } } if(query(qa,qa,1)==1) return 0; else return 1;}int main() { scanf("%d %d",&n,&m); for(int i=1; i<=n; i++) { scanf("%d",&a[i]); } for(int i=1; i<=m; i++) { scanf("%d %d %d",&q[i].type,&q[i].l,&q[i].r); } int l=1,r=n; int ans=n+1; scanf("%d",&qa); while(l<=r) { int mid=(l+r)>>1; if(check(mid)) { ans=min(ans,mid); r=mid-1; } else { l=mid+1; } } printf("%d\n",ans);}

转载于:https://www.cnblogs.com/birchtree/p/9858037.html

你可能感兴趣的文章
Spring Cloud Stream消费失败后的处理策略(三):使用DLQ队列(RabbitMQ)
查看>>
PKUWC2018 5/6
查看>>
As-If-Serial 理解
查看>>
洛谷P1005 矩阵取数游戏
查看>>
在Silverlight中使用HierarchicalDataTemplate为TreeView实现递归树状结构
查看>>
无线通信基础(一):无线网络演进
查看>>
关于python中带下划线的变量和函数 的意义
查看>>
linux清空日志文件内容 (转)
查看>>
Ajax : load()
查看>>
MySQL-EXPLAIN执行计划Extra解释
查看>>
图片点击轮播(三)-----2017-04-05
查看>>
直播技术细节3
查看>>
《分布式服务架构:原理、设计于实战》总结
查看>>
java中new一个对象和对象=null有什么区别
查看>>
字母和数字键的键码值(keyCode)
查看>>
01_1_准备ibatis环境
查看>>
JavaScript中的BOM和DOM
查看>>
360浏览器兼容模式 不能$.post (不是a 连接 onclick的问题!!)
查看>>
spring注入Properties
查看>>
jmeter(五)创建web测试计划
查看>>