[ZJOI2013]K大数查询——整体二分
题目描述
有N个位置,M个操作。操作有两种,每次操作如果是:
1 a b c:表示在第a个位置到第b个位置,每个位置加上一个数c2 a b c:表示询问从第a个位置到第b个位置,第C大的数是多少。
思路
比较基础的整体二分。我们二分出$mid,对于值域[l,r]对应的操作[L,R]$,若为操作1,则考虑把$val>mid$的插入线段树中,表示比$mid$大的值的个数,若为操作2,先询问$[q[i].l,q[i].r]$中比$mid$大的值的个数,然后把当前询问填到左右区间再处理。讲的很简单,调过来整体二分原理的一些东西,,,毕竟这题还是比较板子的。
code
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define I inline
#define smid (l+r>>1)
#define lch (now<<1)
#define rch (now<<1|1)
using namespace std;
const int N=;
typedef long long LL;
int n,m,tot;
LL ans[N];
struct segment
{
LL sum,pls;
}sgt[N<<];
struct node
{
int l,r,k,op,id;
}q[N<<],q1[N<<],q2[N<<]; I int read()
{
int x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
} I LL readll()
{
LL x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
} I void pushup(int now)
{
sgt[now].sum=sgt[lch].sum+sgt[rch].sum;
} I void pushdown(int now,int l,int r)
{
if(!sgt[now].pls)return;
sgt[lch].pls+=sgt[now].pls;
sgt[rch].pls+=sgt[now].pls;
sgt[lch].sum+=(smid-l+)*sgt[now].pls;
sgt[rch].sum+=(r-smid)*sgt[now].pls;
sgt[now].pls=;
} I void modify(int now,int l,int r,int x,int y,int val)
{
if(x<=l&&r<=y)
{
sgt[now].pls+=val;
sgt[now].sum+=(r-l+)*val;
return;
}
pushdown(now,l,r);
if(x<=smid)modify(lch,l,smid,x,y,val);
if(smid<y)modify(rch,smid+,r,x,y,val);
pushup(now);
} I LL query(int now,int l,int r,int x,int y)
{
if(x<=l&&r<=y)return sgt[now].sum;
pushdown(now,l,r);
LL res=;
if(x<=smid)res+=query(lch,l,smid,x,y);
if(smid<y)res+=query(rch,smid+,r,x,y);
pushup(now);
return res;
} I 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].op==)ans[q[i].id]=l;
return;
}
int mid=(l+r>>),cnt1=,cnt2=;
for(int i=L;i<=R;i++)
{
if(q[i].op==)
{
if(q[i].k>mid)
modify(,,n,q[i].l,q[i].r,),q2[++cnt2]=q[i];
else q1[++cnt1]=q[i];
}
else
{
LL tmp=query(,,n,q[i].l,q[i].r);
if(q[i].k>tmp)q[i].k-=tmp,q1[++cnt1]=q[i];
else q2[++cnt2]=q[i];
}
}
for(int i=;i<=cnt2;i++)if(q2[i].op==)modify(,,n,q2[i].l,q2[i].r,-);
for(int i=;i<=cnt1;i++)q[L+i-]=q1[i];
for(int i=;i<=cnt2;i++)q[L+cnt1+i-]=q2[i];
solve(l,mid,L,L+cnt1-);solve(mid+,r,L+cnt1,R);
} int main()
{
n=read();m=read();
for(int i=;i<=m;i++)
{
q[i].op=read();q[i].l=read();q[i].r=read();q[i].k=readll();
if(q[i].op==)q[i].id=++tot;
}
solve(-n,n,,m);
for(int i=;i<=tot;i++)printf("%lld\n",ans[i]);
}
[ZJOI2013]K大数查询——整体二分的更多相关文章
- P3332 [ZJOI2013]K大数查询 整体二分
终于入门整体二分了,勉勉强强算是搞懂了一个题目吧. 整体二分很多时候可以比较好的离线处理区间\(K\)大值的相关问题.考虑算法流程: 操作队列\(arr\),其中有询问和修改两类操作. 每次在答案的可 ...
- BZOJ 3110: [Zjoi2013]K大数查询 [整体二分]
有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c如果是2 a b c形式,表示询问从第a个位置到第b个位置,第C大的数是多少. N ...
- BZOJ3110:[ZJOI2013]K大数查询(整体二分)
Description 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c.如果是2 a b c形式,表示询问从第a个位置到第b个位 ...
- BZOJ.3110.[ZJOI2013]K大数查询(整体二分 树状数组/线段树)
题目链接 BZOJ 洛谷 整体二分求的是第K小(利用树状数组).求第K大可以转为求第\(n-K+1\)小,但是这样好像得求一个\(n\). 注意到所有数的绝对值\(\leq N\),将所有数的大小关系 ...
- BZOJ 3110 [Zjoi2013]K大数查询 ——整体二分
[题目分析] 整体二分显而易见. 自己YY了一下用树状数组区间修改,区间查询的操作. 又因为一个字母调了一下午. 貌似树状数组并不需要清空,可以用一个指针来维护,可以少一个log 懒得写了. [代码] ...
- 【bzoj3110】[Zjoi2013]K大数查询 整体二分+树状数组区间修改
题目描述 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c.如果是2 a b c形式,表示询问从第a个位置到第b个位置,第C大的数 ...
- BZOJ3110:[ZJOI2013]K大数查询(整体二分版)
浅谈离线分治算法:https://www.cnblogs.com/AKMer/p/10415556.html 题目传送门:https://lydsy.com/JudgeOnline/problem.p ...
- BZOJ 3110 [ZJOI2013]K大数查询 (整体二分+线段树)
和dynamic rankings这道题的思想一样 只不过是把树状数组换成线段树区间修改,求第$K$大的而不是第$K$小的 这道题还有负数,需要离散 #include <vector> # ...
- 【BZOJ-3110】K大数查询 整体二分 + 线段树
3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 6265 Solved: 2060[Submit][Sta ...
随机推荐
- 启动一个Activity的几种方式
在Android中我们可以通过下面两种方式来启动一个新的Activity,注意这里是怎么启动,而非 启动模式!!分为显示启动和隐式启动! 1. 显式启动:通过包名来启动,写法如下: ①最常见的: st ...
- centos 7安装rac 11gR2时运行root.sh报错找不到ohas服务(ohasd failed to start)
单独在linux 7中为ohasd设置一个服务.步骤如下1. 创建服务ohas.service的服务文件并赋予权限touch /usr/lib/systemd/system/ohas.servicec ...
- 从0开始学FreeRTOS-(任务调度)-4
大家晚上好,我是杰杰,最近挺忙的,好久没有更新了,今天周末就吐血更新一下吧! # 前言 `FreeRTOS`是一个是实时内核,任务是程序执行的最小单位,也是调度器处理的基本单位,移植了`FreeRTO ...
- 分库分表(6)--- SpringBoot+ShardingSphere实现分表+ 读写分离
分库分表(6)--- ShardingSphere实现分表+ 读写分离 有关分库分表前面写了五篇博客: 1.分库分表(1) --- 理论 2.分库分表(2) --- ShardingSphere(理论 ...
- 微信退款(APP和公众号一样)
/** * 将xml转为array * @param string $xml xml字符串 * @return array 转换得到的数组 */ public function xml2array($ ...
- e课表项目第二次冲刺周期第八天
昨天完成了什么? 昨天,我们组商量讨论了二层界面的设计,添加课程所需要的信息大概有:课程名称.教室.任课教师.上课时间.类型(单周.双周.单双周)以及备注等等.然后,我们通过界面的UI设计,让我们软件 ...
- e课表项目第二次冲刺周期第一天
昨天干了什么? 昨天与我们小组的成员商量了一个重大的决定,由于我们第一次冲刺周期的成果,就是我们决定我们要转型发展. 今天干了什么? 查阅相关的资料,我们正式决定要做一款学习的课程表APP,把简易作为 ...
- Ubuntu 安装中文
系统环境:
- NServiceBus+Saga开发分布式应用
前言 当你在处理异步消息时,每个单独的消息处理程序都是一个单独的handler,每个handler之间互不影响.这时如果一个消息依赖另一个消息的状态呢? 这时业务逻辑怎么处理? ...
- Knative 实战:基于 Kafka 实现消息推送
作者 | 元毅 阿里云智能事业群高级开发工程师 导读:当前在 Knative 中已经提供了对 Kafka 事件源的支持,那么如何基于 Kafka 实现消息推送呢?本文作者将以阿里云 Kafka 产品为 ...