【BZOJ3110】K大数查询(整体二分)
【BZOJ3110】K大数查询(整体二分)
题面
题解
看了很久整体二分
一直不知道哪里写错了
。。。
又把树状数组当成线段树区间加法来用了。。
整体二分还是要想清楚在干什么:
我们考虑第\(K\)大是什么
就是还有\(K-1\)个比他小
这样子就可以考虑二分之后如何\(check\)
当前二分出一个答案之后
按照时间顺序检查每个操作
如果是添加:
如果加进去的值比二分的答案要小
证明对结果没有贡献
直接丢到左区间里不管
否则线段树做区间加法
如果是修改
检查一下当前是否满足
然后分类丢到左右区间
总的来说
想清楚还是挺容易的
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<queue>
using namespace std;
#define ll long long
#define RG register
#define MAX 52000
#define lson (now<<1)
#define rson (now<<1|1)
inline int read()
{
RG int x=0,t=1;RG char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=-1,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return x*t;
}
struct Node
{
int clr;
int ly;
ll sum;
void clear(){clr=ly=sum=0;}
}t[MAX<<3];
int n,m,ans[MAX];
void putlazy(int now,int l,int r,int w)
{
t[now].sum+=w*(r-l+1);
t[now].ly+=w;
}
void clr(int now)
{
if(t[now].clr)
{
t[lson].clear();
t[rson].clear();
t[lson].clr=1;
t[rson].clr=1;
t[now].clr=0;
}
}
void pushdown(int now,int l,int r)
{
int mid=(l+r)>>1;
clr(now);
putlazy(lson,l,mid,t[now].ly);
putlazy(rson,mid+1,r,t[now].ly);
t[now].ly=0;
}
void Modify(int now,int l,int r,int L,int R)
{
pushdown(now,l,r);
if(l==L&&r==R){putlazy(now,l,r,1);return;}
t[now].sum+=R-L+1;
int mid=(l+r)>>1;
if(R<=mid)Modify(lson,l,mid,L,R);
else if(L>mid)Modify(rson,mid+1,r,L,R);
else{Modify(lson,l,mid,L,mid);Modify(rson,mid+1,r,mid+1,R);}
}
ll Query(int now,int l,int r,int L,int R)
{
pushdown(now,l,r);
if(L<=l&&r<=R)return t[now].sum;
int mid=(l+r)>>1;ll ret=0;
if(L<=mid)ret+=Query(lson,l,mid,L,R);
if(R>mid)ret+=Query(rson,mid+1,r,L,R);
return ret;
}
struct Ask{int opt,l,r,c,id;}p[MAX],p1[MAX],p2[MAX];
void Work(int L,int R,int l,int r)
{
if(L>R)return;
if(l==r)
{
for(int i=L;i<=R;++i)ans[p[i].id]=l;
return;
}
int mid=(l+r)>>1;
int t1=0,t2=0;
for(int i=L;i<=R;++i)
{
if(p[i].opt==1)
{
if(p[i].c<=mid)p1[++t1]=p[i];
else
{
p2[++t2]=p[i];
Modify(1,1,n,p[i].l,p[i].r);
}
}
else
{
ll ss=Query(1,1,n,p[i].l,p[i].r);
if(ss>=p[i].c)p2[++t2]=p[i];
else p[i].c-=ss,p1[++t1]=p[i];
}
}
for(int i=1;i<=t1;++i)p[L+i-1]=p1[i];
for(int i=1;i<=t2;++i)p[L+t1+i-1]=p2[i];
t[1].clear();t[1].clr=1;
Work(L,L+t1-1,l,mid);Work(L+t1,R,mid+1,r);
}
int main()
{
n=read();m=read();
int sum=0;
for(int i=1;i<=m;++i)
{
p[i].opt=read();p[i].l=read();p[i].r=read();p[i].c=read();
if(p[i].opt==2)p[i].id=++sum;
}
Work(1,m,-n,n);
for(int i=1;i<=sum;++i)printf("%d\n",ans[i]);
return 0;
}
【BZOJ3110】K大数查询(整体二分)的更多相关文章
- 【BZOJ-3110】K大数查询 整体二分 + 线段树
3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 6265 Solved: 2060[Submit][Sta ...
- BZOJ 3110 K大数查询 | 整体二分
BZOJ 3110 K大数查询 题面 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c 如果是2 a b c形式,表示询问从第a个 ...
- [ZJJOI2013]K大数查询 整体二分
[ZJJOI2013]K大数查询 链接 luogu 思路 整体二分. 代码 #include <bits/stdc++.h> #define ll long long using name ...
- BZOJ3110:[ZJOI2013]K大数查询(整体二分)
Description 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c.如果是2 a b c形式,表示询问从第a个位置到第b个位 ...
- 【bzoj3110】[Zjoi2013]K大数查询 整体二分+树状数组区间修改
题目描述 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c.如果是2 a b c形式,表示询问从第a个位置到第b个位置,第C大的数 ...
- 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 ...
- BZOJ.3110.[ZJOI2013]K大数查询(整体二分 树状数组/线段树)
题目链接 BZOJ 洛谷 整体二分求的是第K小(利用树状数组).求第K大可以转为求第\(n-K+1\)小,但是这样好像得求一个\(n\). 注意到所有数的绝对值\(\leq N\),将所有数的大小关系 ...
- [ZJOI2013]K大数查询——整体二分
题目描述 有N个位置,M个操作.操作有两种,每次操作如果是: 1 a b c:表示在第a个位置到第b个位置,每个位置加上一个数c 2 a b c:表示询问从第a个位置到第b个位置,第C大的数是多少. ...
- BZOJ 3110 [Zjoi2013]K大数查询 ——整体二分
[题目分析] 整体二分显而易见. 自己YY了一下用树状数组区间修改,区间查询的操作. 又因为一个字母调了一下午. 貌似树状数组并不需要清空,可以用一个指针来维护,可以少一个log 懒得写了. [代码] ...
随机推荐
- elasticsearch2.3.3安装
本文来自我的github pages博客http://galengao.github.io/ 即www.gaohuirong.cn 摘要: 作者原来搭建的环境是0.95版本 现在升级到2.3.3版本, ...
- 有了Openvswitch和Docker,终于可以做《TCP/IP详解》的实验了!
所有做过网络编程的程序员,想必都会看<TCP/IP详解>卷一:协议 后来出了第二版,但是由于第一版才是Rechard Stevens的原版,本人还是多次看了第一版. 对这一版印象最深的就是 ...
- 阿里云CentOS 7系统挂载SSD云盘的教程_Linux
一.查看SSD云盘 sudo fdisk -l Disk /dev/vda: 42.9 GB, 42949672960 bytes, 83886080 sectors Units = sectors ...
- 又是一个愚蠢的错误,皆因.xml而起
论java中的.xml到底有多坑?! 感觉自己都快哭了,再一次被.xml给坑了一下,这次坑的太狠了,一下子导致自己浪费了昨天一下午,一晚上,今天一上午和半个下午呀,中间的过程真的是乏善可陈呀,各 ...
- UVALive - 4329 Ping pong 树状数组
这题不是一眼题,值得做. 思路: 假设第个选手作为裁判,定义表示在裁判左边的中的能力值小于他的人数,表示裁判右边的中的能力值小于他的人数,那么可以组织场比赛. 那么现在考虑如何求得和数组.根据的定义知 ...
- HDU - 2614 dfs
思路:记录当前用的最大时间即刚解决的问题花费的时间,下一个应该做的题的时间必须大于等于刚才的. AC代码 #include <cstdio> #include <cmath> ...
- Selenium里可以自行封装与get_attribute对应的set_attribute方法
我们在做UI自动化测试的过程中,某些情况会遇到,需要操作WebElement属性的情况. 假设现在我们需要获取一个元素的title属性,我们可以先找到这个元素,然后利用get_attribute方法获 ...
- H3C虚拟化之IRF
SA system-view irf domain 10 irf member 1 ren 1 y int ten 1/0/50 shu qu irf-port 1/1 port group int ...
- java 集合框架(十四)Queue
一.概述 Queue一种队列结构集合,用来存储将要进行处理的元素.通常以FIFO的方式排序元素,但这并不是必须的.比如优先度队列就是一个例外,它是以元素的值来排序.但无论怎样,每个Queue的实现都必 ...
- SQL中partition关键字的使用
最近在写后台语句时候,运用到了partition这样一个关键字. 先大致说一下背景,有一种数据表,如下 现在需要取出,每一个人最近的一次打卡时间. 思路是,先把数据按照人名分组,然后在每个组里面按照时 ...