bzoj 3110 [Zjoi2013]K大数查询 整体二分
来源:互联网 发布:matlab 数组画图 编辑:程序博客网 时间:2024/05/16 18:11
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
输出每个询问的结果
大概是什么加上ZJOI这四个字母都变成刁钻题了吧...
既然是整体二分题,先考虑如何二分呢,如果根据一般的套路,对于直接对于时间进行二分,我们并不能找到满足二分的性质,但是有二分性质的肯定是一个与时间有关的量,那么就是答案的数值了。
由于询问的区间固定,那么如果把一部分的数字加进来,答案满足,那么加更多的数字一定满足,所以我们找到了可以二分的特性了。
那么根据以上特性,在区间[l,r]对于加入操作每次把大于等于mid的数字加进来,对于查询操作看一看查询区间是否能够满足有k个数,如果已经满足了,那么答案[mid,r]这个区间递归得到答案,如果不满足说明答案在[l,mid-1]这个区间,就将当前这个查询的k减去已经构成的答案,再去递归求解即可得到答案。
由于输入的数值有负数的如果直接进行二分常数略大,所以可以选择先离散化一下即可。
下附AC代码
#include<iostream>#include<stdio.h>#include<string.h>#include<algorithm>#define mid ((nl+nr)>>1)#define lson (now<<1)#define rson ((now<<1)|1)#define maxn 500005using namespace std;typedef long long ll;struct nod{ll f,l,r,val,pos,flag;}q[maxn];bool operator<(nod a,nod b){return a.flag==b.flag ? a.pos<b.pos : a.flag<b.flag;}ll sz;ll n,m;ll ans[maxn];ll tot;ll a[maxn],b[maxn];ll id[maxn],temp[maxn];ll sum[maxn<<2],lazy[maxn<<2],flag[maxn<<2];void pushup(ll now){sum[now]=sum[lson]+sum[rson];}void pushdown(ll now,ll nl,ll nr){if(lazy[now]){sum[lson]+=lazy[now]*(mid-nl+1);sum[rson]+=lazy[now]*(nr-mid);lazy[lson]+=lazy[now];lazy[rson]+=lazy[now];lazy[now]=0;}return;}void update(ll ql,ll qr,ll add,ll nl,ll nr,ll now){if(nl>nr || ql>qr) return;if(ql<=nl && nr<=qr){sum[now]+=add*(nr-nl+1);lazy[now]+=add;return;}pushdown(now,nl,nr);if(ql<=mid) update(ql,qr,add,nl,mid,lson);if(mid<qr) update(ql,qr,add,mid+1,nr,rson);pushup(now);}ll query(ll ql,ll qr,ll nl,ll nr,ll now){if(nl>nr || ql>qr) return 0;if(ql<=nl && nr<=qr){return sum[now];}pushdown(now,nl,nr);ll ans=0;if(ql<=mid) ans+=query(ql,qr,nl,mid,lson);if(mid<qr) ans+=query(ql,qr,mid+1,nr,rson);pushup(now);return ans;}void dfs(ll nl,ll nr,ll ql,ll qr){if(ql>qr || nl>nr) return;if(nl==nr){for(ll i=ql;i<=qr;i++){ans[q[i].pos]=nl;}return;}ll l1=ql,cnt=0;for(ll i=ql;i<=qr;i++){if(q[i].f==1){if(q[i].val>b[mid]){update(q[i].l,q[i].r,1,1,n,1);q[i].flag=2;}else{cnt++;q[i].flag=1;}}else{ll now=query(q[i].l,q[i].r,1,n,1);if(now>=q[i].val){q[i].flag=2;}else{cnt++;q[i].val-=now;q[i].flag=1;}}}for(ll i=ql;i<=qr;i++){if(q[i].f==1){if(q[i].val>b[mid]){update(q[i].l,q[i].r,-1,1,n,1);}}}sort(q+ql,q+qr+1);dfs(nl,mid,ql,ql+cnt-1);dfs(mid+1,nr,ql+cnt,qr);}int main(){scanf("%lld%lld",&n,&m);for(ll i=1;i<=m;i++){scanf("%lld%lld%lld%lld",&q[i].f,&q[i].l,&q[i].r,&q[i].val);q[i].pos=i;if(q[i].f==1){b[++tot]=q[i].val;}}sort(b+1,b+1+tot);sz=unique(b+1,b+1+tot)-(b+1);memset(ans,-1,sizeof(ans));dfs(1,sz,1,m);for(ll i=1;i<=m;i++)q[i].flag=0;sort(q+1,q+1+m);for(ll i=1;i<=m;i++)if(q[i].f==2){if(ans[i]==-1)printf("%lld\n",ans[i]);elseprintf("%lld\n",b[ans[i]]);}}
阅读全文
0 0
- BZOJ-3110-K大数查询-ZJOI2013-整体二分
- bzoj 3110: [Zjoi2013]K大数查询(树套树,整体二分)
- [BZOJ]3110: [Zjoi2013]K大数查询 整体二分+线段树
- bzoj 3110 [Zjoi2013]K大数查询 整体二分
- 【BZOJ】【P3110】【Zjoi2013】【K大数查询】【题解】【整体二分】
- 【BZOJ 3110】 [Zjoi2013]K大数查询 整体二分+树状数组区间修改
- 【BZOJ】3110 [Zjoi2013]K大数查询 整体二分+树状数组 || 树套树
- BZOJ 3110 [Zjoi2013]K大数查询(整体二分+树状数组)
- [Zjoi2013]K大数查询 整体二分/树套树
- [整体二分] BZOJ3110: [Zjoi2013]K大数查询
- bzoj 3110 K大数查询(整体二分)
- bzoj 3110 K大数查询 整体二分
- BZOJ 3110 [Zjoi2013]K大数查询 (整体二分 + 树状数组或线段树处理区间合值)
- HDU 5412 CRB and Queries && BZOJ 3110: [Zjoi2013]K大数查询 (整体二分+树状数组/线段树)
- BZOJ_P3110 [ZJOI2013]K大数查询(线段树+整体二分)
- 【BZOJ3110】K大数查询(ZJOI2013)-整体二分+线段树
- [BZOJ3110][ZJOI2013]K大数查询-CDQ分治-整体二分
- BZOJ 3110 ZJOI2013 K大数查询 树套树
- ios11以及iphonex适配
- Stanford机器学习---第九讲. 聚类
- Linux防火墙端口配置和ftp修改端口
- Single Image Haze Removal Using Dark Channel Prior翻译
- dom编程艺术一些笔记
- bzoj 3110 [Zjoi2013]K大数查询 整体二分
- 购物车案例_02
- HGDB数据库对象与模式的关系
- Js立即执行函数
- 五款Android 应用的自动化测试工具
- Caused by: Parent package is not defined: json-default
- JAVA中的修饰符
- 失去的内容记录
- native api 之 注册表