博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
HDU5649 DZY Loves Sorting 线段树
阅读量:4315 次
发布时间:2019-06-06

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

题意:BC 76 div1 1004 有中文题面

然后奉上官方题解:

这是一道良心的基础数据结构题。

我们二分a[k]的值,假设当前是mid,然后把大于mid的数字标为1,不大于mid的数字标为0。然后对所有操作做完以后检查一下a[k]位置上是0还是1。

因为只有两种值,所以操作还是不难做的。只要用一个线段树,支持区间求和、区间赋值即可。

这样要排序一个区间时只要查询一下里面有几个1和几个0,然后把前半段赋值为0,后半段赋值为1即可(降序的话就是反过来)。

复杂度是O(mlog^2n)。

#include 
#include
#include
#include
using namespace std;typedef long long LL;const int N=1e5+5;int a[N],b[N],T,n,m,k;int sum[N<<2];int lz[N<<2];int pushup(int rt){ sum[rt]=sum[rt<<1]+sum[rt<<1|1];}void pushdown(int rt,int l,int r){ if(lz[rt]!=-1){ int mid=(l+r)>>1; sum[rt<<1]=lz[rt]*(mid-l+1); sum[rt<<1|1]=lz[rt]*(r-mid); lz[rt<<1]=lz[rt<<1|1]=lz[rt]; lz[rt]=-1; } }void build(int rt,int l,int r){ lz[rt]=-1; if(l==r){ sum[rt]=b[l]; return; } int mid=(l+r)>>1; build(rt<<1,l,mid); build(rt<<1|1,mid+1,r); pushup(rt); }void update(int rt,int l,int r,int x,int y,int t){ if(x<=l&&r<=y){ sum[rt]=t*(r-l+1); lz[rt]=t; return; } int mid=(l+r)>>1; pushdown(rt,l,r); if(x<=mid)update(rt<<1,l,mid,x,y,t); if(y>mid)update(rt<<1|1,mid+1,r,x,y,t); pushup(rt);}int query(int rt,int l,int r,int x,int y){ if(x<=l&&r<=y)return sum[rt]; int mid=(l+r)>>1; pushdown(rt,l,r); if(y<=mid)return query(rt<<1,l,mid,x,y); else if(x>mid)return query(rt<<1|1,mid+1,r,x,y); return query(rt<<1,l,mid,x,y)+query(rt<<1|1,mid+1,r,x,y);}struct op{ int x,y,t;}o[N];bool check(int x){ for(int i=1;i<=n;++i) b[i]=a[i]>x?1:0; build(1,1,n); for(int i=1;i<=m;++i){ int tmp=query(1,1,n,o[i].x,o[i].y); if(!o[i].t){ if(o[i].x<=o[i].y-tmp)update(1,1,n,o[i].x,o[i].y-tmp,0); if(o[i].y-tmp+1<=o[i].y)update(1,1,n,o[i].y-tmp+1,o[i].y,1); } else{ if(o[i].x<=o[i].x+tmp-1)update(1,1,n,o[i].x,o[i].x+tmp-1,1); if(o[i].x+tmp<=o[i].y)update(1,1,n,o[i].x+tmp,o[i].y,0); } } return query(1,1,n,k,k)==1; }int main(){ scanf("%d",&T); while(T--){ 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",&o[i].t,&o[i].x,&o[i].y); scanf("%d",&k); int l=1,r=n; while(l
>1; if(check(mid))l=mid+1; else r=mid; } printf("%d\n",(l+r)>>1); } return 0;}
View Code

 

转载于:https://www.cnblogs.com/shuguangzw/p/5304110.html

你可能感兴趣的文章
获取设备实际宽度
查看>>
Notes on <High Performance MySQL> -- Ch3: Schema Optimization and Indexing
查看>>
Alpha冲刺(10/10)
查看>>
数组Array的API2
查看>>
为什么 Redis 重启后没有正确恢复之前的内存数据
查看>>
No qualifying bean of type available问题修复
查看>>
第四周助教心得体会
查看>>
spfile
查看>>
Team Foundation Service更新:改善了导航和项目状态速查功能
查看>>
WordPress资源站点推荐
查看>>
Python性能鸡汤
查看>>
android Manifest.xml选项
查看>>
Cookie/Session机制具体解释
查看>>
ATMEGA16 IOport相关汇总
查看>>
有意思的cmd命令
查看>>
js正則表達式语法
查看>>
Git学习系列-Git基本概念
查看>>
c#多个程序集使用app.config 的解决办法
查看>>
Linux+Apache+PHP+MySQL服务器环境配置(CentOS篇)
查看>>
Linux下获取本机IP地址的代码
查看>>