【BZOJ3110】K大数查询(整体二分)

题面

BZOJ

题解

看了很久整体二分

一直不知道哪里写错了

。。。

又把树状数组当成线段树区间加法来用了。。

整体二分还是要想清楚在干什么:

我们考虑第\(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大数查询(整体二分)的更多相关文章

  1. 【BZOJ-3110】K大数查询 整体二分 + 线段树

    3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 6265  Solved: 2060[Submit][Sta ...

  2. BZOJ 3110 K大数查询 | 整体二分

    BZOJ 3110 K大数查询 题面 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c 如果是2 a b c形式,表示询问从第a个 ...

  3. [ZJJOI2013]K大数查询 整体二分

    [ZJJOI2013]K大数查询 链接 luogu 思路 整体二分. 代码 #include <bits/stdc++.h> #define ll long long using name ...

  4. BZOJ3110:[ZJOI2013]K大数查询(整体二分)

    Description 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c.如果是2 a b c形式,表示询问从第a个位置到第b个位 ...

  5. 【bzoj3110】[Zjoi2013]K大数查询 整体二分+树状数组区间修改

    题目描述 有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c.如果是2 a b c形式,表示询问从第a个位置到第b个位置,第C大的数 ...

  6. P3332 [ZJOI2013]K大数查询 整体二分

    终于入门整体二分了,勉勉强强算是搞懂了一个题目吧. 整体二分很多时候可以比较好的离线处理区间\(K\)大值的相关问题.考虑算法流程: 操作队列\(arr\),其中有询问和修改两类操作. 每次在答案的可 ...

  7. BZOJ 3110: [Zjoi2013]K大数查询 [整体二分]

    有N个位置,M个操作.操作有两种,每次操作如果是1 a b c的形式表示在第a个位置到第b个位置,每个位置加入一个数c如果是2 a b c形式,表示询问从第a个位置到第b个位置,第C大的数是多少. N ...

  8. BZOJ.3110.[ZJOI2013]K大数查询(整体二分 树状数组/线段树)

    题目链接 BZOJ 洛谷 整体二分求的是第K小(利用树状数组).求第K大可以转为求第\(n-K+1\)小,但是这样好像得求一个\(n\). 注意到所有数的绝对值\(\leq N\),将所有数的大小关系 ...

  9. [ZJOI2013]K大数查询——整体二分

    题目描述 有N个位置,M个操作.操作有两种,每次操作如果是: 1 a b c:表示在第a个位置到第b个位置,每个位置加上一个数c 2 a b c:表示询问从第a个位置到第b个位置,第C大的数是多少. ...

  10. BZOJ 3110 [Zjoi2013]K大数查询 ——整体二分

    [题目分析] 整体二分显而易见. 自己YY了一下用树状数组区间修改,区间查询的操作. 又因为一个字母调了一下午. 貌似树状数组并不需要清空,可以用一个指针来维护,可以少一个log 懒得写了. [代码] ...

随机推荐

  1. jQuery源码逐行分析学习02(第一部分:jQuery的一些变量和函数)

    第一次尝试使用Office Word,方便程度大大超过网页在线编辑,不过初次使用,一些内容不甚熟悉,望各位大神见谅~ 在上次的文章中,把整个jQuery的结构进行了梳理,得到了整个jQuery的简化结 ...

  2. nodejs http post 请求带参数

    // We need this to build our post string var querystring = require('querystring'); var http = requir ...

  3. Linux下绝对经典的命令

    1.使用远程终端时,可以使用如下命令: screen tmux 2.下载文件可以使用如下命令: curl wget 3.压缩解压缩可以使用: tar .zip.rar 4.使用抓包工具 tcpdump ...

  4. ★Linux命令行操作技巧(作为服务器端)

    1.统计某个目录下总共有多少个文件(递归统计所有子目录)ls -lR|grep "^-"|wc -l

  5. MSSql Server 批量插入数据优化

    针对批量入库, .Net Framework  提供了一个批量入库Class : SqlBulkCopy , 批量入库性能不错,经测试 四万左右数据 2秒入库. 以下是测试Demo , 使用外部传入事 ...

  6. qemu-trustzone编译&运行(包含linux内核的编译方法)

    由于之前都是用的mtk6797开发板,回到实验室之后想要做实验的话需要弄一个支持trustzone的qemu,在这里记录一下我的编译和调试过程.本来最近一直忙着看论文和写论文,但是忽然发现自己在实验部 ...

  7. Python+Selenium基础篇之1-环境搭建

    Python + Selenium 自动化环境搭建过程 1. 所需组建 1.1 Selenium for python 1.2 Python 1.3 Notepad++ 作为刚初学者,这里不建议使用P ...

  8. vim使用教程

    vim的学习曲线相当的大(参看各种文本编辑器的学习曲线),所以,如果你一开始看到的是一大堆VIM的命令分类,你一定会对这个编辑器失去兴趣的.下面的文章翻译自<Learn Vim Progress ...

  9. C++ string数据类型的实现

    #include <cstdlib> #include <cstring> class Mystring { public: Mystring(const char * pda ...

  10. AHB/APB简介

    AHB AHB总线互联结构图 随着深亚微米工艺技术日益成熟,集成电路芯片的规模越来越大.数字IC从基于时序驱动的设计方法,发展到基于IP复用的设计方法,并在SOC设计中得到了广泛应用.在基于IP复用的 ...