BZOJ_P3110 [ZJOI2013]K大数查询(线段树+整体二分)
来源:互联网 发布:安卓全球电视直播软件 编辑:程序博客网 时间:2024/05/20 23:32
BZOJ传送门
Time Limit: 20 Sec Memory Limit: 512 MB
Submit: 3134 Solved: 1326
[Submit][Status][Discuss]
Description
有N个位置,M个操作。操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c
如果是2 a b c形式,表示询问从第a个位置到第b个位置,第C大的数是多少。
Input
第一行N,M
接下来M行,每行形如1 a b c或2 a b c
Output
输出每个询问的结果
Sample Input
2 5
1 1 2 1
1 1 2 2
2 1 1 2
2 1 1 1
2 1 2 3
Sample Output
1
2
1
HINT
【样例说明】
第一个操作 后位置 1 的数只有 1 , 位置 2 的数也只有 1 。 第二个操作 后位置 1的数有 1 、 2 ,位置 2 的数也有 1 、 2 。 第三次询问 位置 1 到位置 1 第 2 大的数 是1 。 第四次询问 位置 1 到位置 1 第 1 大的数是 2 。 第五次询问 位置 1 到位置 2 第 3大的数是 1 。
N,M<=50000,N,M<=50000
a<=b<=N
1操作中abs(c)<=N
2操作中abs(c)<=Maxlongint
Source
读了半天题都读错了QuQ,果然是我语文不好,返回的是第K大数的位置
第一道整体二分,用了离线处理(貌似网上整体二分的资料不多?),先思考如果只有一个询问,如何二分?很简单嘛,在[L,R]的区间中取M=(L+R)>>1,计算在[L,M]区间中比询问的数大的有多少个。而整体二分,自然要整体,在二分区间的同时将所有询问一起二分处理。下面就是主要的思路
- 如果二分的区间L==R那么答案在这个区间的全部为L(递归出口1)
- 如果(l>r)返回(递归出口2)
- 将询问分类,0类的答案在[L,M]中,1类的答案在[M+1,R]中
- 如果是增加类型,考虑它的贡献如果v>M,就在[q.l,q.r]中每位添加1,归为1类,否则归为0类
- 如果是查询类型,考虑答案位置,统计区间中比v大的个数,如果v<=s,答案在[M+1,R]中,归为1类,否则答案在[L,M]中,归为0类
对每一个询问我们都需要判定一下,以决定它被划分到哪一个答案的区间里。这个判定过程就是通过比较比二分的M大的数的个数和v。同时我们看到,如果比二分的M大的数的个数小于v了,我们是要去寻找小的答案,那么这些比M大的数在以后的递归里始终会对答案有贡献,所以我们没必要去做重复的工作,只需要把这些数的个数累积到贡献里,以后递归的时候就不用考虑这些数了 摘录自ZigZag Blog
- 每次清空线段树要打标记,不能硬清
#include<cstdio>#include<cstring>#include<algorithm>#include<iostream>using namespace std;#define N 50005#define lc o*2#define rc o*2+1#define done seg.ql=q[i].l,seg.qr=q[i].rstruct SegmentTree{ int ql,qr;bool clr[N<<2]; int add[N<<2],sum[N<<2]; inline void init(){sum[1]=add[1]=0,clr[1]=1;} inline void updata(int o){sum[o]=sum[lc]+sum[rc];} inline void pushdown(int o,int L,int R){ if(clr[o]){sum[lc]=sum[rc]=add[lc]=add[rc]=0, clr[lc]=clr[rc]=1,clr[o]=0;} int M=(L+R)>>1; if(add[o]){add[lc]+=add[o],add[rc]+=add[o]; sum[lc]+=(M-L+1)*add[o],sum[rc]+=(R-M)*add[o];add[o]=0;} } void Add(int o,int L,int R){ if(ql<=L&&R<=qr){add[o]++,sum[o]+=(R-L+1);return;} int M=(L+R)>>1;pushdown(o,L,R); if(ql<=M) Add(lc,L,M);if(qr>M) Add(rc,M+1,R);updata(o); } int Query(int o,int L,int R){ if(ql<=L&&R<=qr){return sum[o];} pushdown(o,L,R);int res=0,M=(L+R)>>1; if(ql<=M) res+=Query(lc,L,M);if(qr>M) res+=Query(rc,M+1,R); return res; }}seg;struct qs{int opt,l,r,v,id,k;}q[N];int n,m;int ans[N];int cmp(qs a,qs b){return a.k==b.k?a.id<b.id:a.k<b.k;}void solve(int L,int R,int l,int r){ if(l>r) return; if(L==R){ for(int i=l;i<=r;i++) if(q[i].opt==2) ans[q[i].id]=L; return; } seg.init(); int M=(L+R)>>1,t=l-1,s; for(int i=l;i<=r;i++){ if(q[i].opt==1){ if(q[i].v>M){done;seg.Add(1,1,n);q[i].k=1;} else{t++,q[i].k=0;} } else{ done;s=seg.Query(1,1,n); if(q[i].v<=s) q[i].k=1; else t++,q[i].k=0,q[i].v-=s; } } sort(q+l,q+r+1,cmp); solve(L,M,l,t);solve(M+1,R,t+1,r);}inline int in(int x=0,char ch=getchar()){ while(ch>'9'||ch<'0') ch=getchar(); while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();return x;}int main(){ n=in(),m=in(); for(int i=1;i<=m;i++){ q[i].opt=in(),q[i].l=in(),q[i].r=in(),q[i].v=in(),q[i].id=i; } memset(ans,-1,sizeof(ans)); solve(0,n,1,m); for(int i=1;i<=m;i++) if(ans[i]!=-1) printf("%d\n",ans[i]); return 0;}
- BZOJ_P3110 [ZJOI2013]K大数查询(线段树+整体二分)
- 【BZOJ3110】K大数查询(ZJOI2013)-整体二分+线段树
- [BZOJ]3110: [Zjoi2013]K大数查询 整体二分+线段树
- [Zjoi2013]K大数查询 整体二分/树套树
- [整体二分] BZOJ3110: [Zjoi2013]K大数查询
- [BZOJ3110][Zjoi2013]K大数查询(主席树套线段树||整体二分 )
- BZOJ 3110 [Zjoi2013]K大数查询 (整体二分 + 树状数组或线段树处理区间合值)
- HDU 5412 CRB and Queries && BZOJ 3110: [Zjoi2013]K大数查询 (整体二分+树状数组/线段树)
- 【BZOJ】【P3110】【Zjoi2013】【K大数查询】【题解】【整体二分】
- BZOJ-3110-K大数查询-ZJOI2013-整体二分
- bzoj 3110: [Zjoi2013]K大数查询(树套树,整体二分)
- bzoj 3110 [Zjoi2013]K大数查询 整体二分
- [BZOJ3110][ZJOI2013]K大数查询-CDQ分治-整体二分
- K大数查询——整体二分套线段树
- bzoj3110 K大数查询(整体二分+线段树)
- BSOJ3723:ZJOI2013 k大数查询 线段树套线段树
- bzoj3110[Zjoi2013]K大数查询 主席树套线段树
- 【ZJOI2013】K 大数查询 ( 树状数组套线段树 )
- ASP.NET 4.0尚未在 Web 服务器上注册
- Memcached—安装
- Zabbix 下监控tomcat多实例,自动化脚本配置
- 项目记录21-- 原来c#框架mediator改lua--02
- 推荐一个清理自己电脑磁盘的磁盘容量图形化软件--WinDirStat
- BZOJ_P3110 [ZJOI2013]K大数查询(线段树+整体二分)
- BZOJ3716: [PA2014]Muzeum
- 控制器的数据传递--block和delegate如何选择
- android上dialog横屏下实现全屏效果
- android四大组件之contentProvider
- android提示Toast的使用
- CodeForces 630 N. Forecast(水~)
- 为什么引入Memcached?
- android-文件存储