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操作中c<=Maxlongint

正解:CDQ分治

解题报告:

  听说这是一道CDQ分治模板题,于是跑来围观。

  CDQ分治的处理十分神奇,一般用于处理有修改、有查询的可离线的题目。  

  这道题目就是每次在一段位置都插入一个数,并动态询问问区间内第几大的数是多少。我们可以考虑CDQ分治。首先二分一个答案x,x指的是询问的答案(题意中说了只能是1到n),我们就对于一下当前这一段的处理序列中,先依次处理,碰到询问就考虑是否可行。如果对于一个询问,发现当前的x之下查询的ans大于那个值,说明答案更小,所以要放到左边去递归处理,但是同时记得,把询问的值减掉查询出的ans,表示这一段肯定比它大,先减掉。至于查询的话,区间修改、区间查询,可以考虑用树状数组。

  总的来说,我对CDQ分治体会还是挺深,但是还是不够熟练,需要多加练习。

 //It is made by jump~
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <ctime>
#include <vector>
#include <queue>
#include <map>
#include <set>
using namespace std;
typedef long long LL;
const int MAXM = ;
int n,m;
int tmp[MAXM],ans[MAXM];
LL c1[MAXM],c2[MAXM];
bool pd[MAXM];
struct ask{
int id,l,r,val,jilu;
}a[MAXM],zuo[MAXM],you[MAXM]; inline int getint()
{
int w=,q=; char c=getchar();
while((c<'' || c>'') && c!='-') c=getchar(); if(c=='-') q=,c=getchar();
while (c>='' && c<='') w=w*+c-'', c=getchar(); return q ? -w : w;
} inline void add(LL x,LL y){
int cun=x;
while(x<=n) {
c1[x]+=y; c2[x]+=cun*y;
x+=x&(-x);
}
} inline LL sum(LL x){
LL total=;
for(int i=x;i>=;i-=(i&-i)) total+=(x+)*c1[i]-c2[i];
return total;
} inline void CDQ(int askl,int askr,int l,int r){
if(askl>askr || l>r) return ;
if(l==r) { for(int i=askl;i<=askr;i++) ans[a[i].jilu]=l; return ; }//答案唯一确定了
int mid=(l+r+)/;
int nowl=,nowr=; LL now;
for(int i=askl;i<=askr;i++) {
if(a[i].id==) {
if(a[i].val>=mid) add(a[i].l,),add(a[i].r+,-),you[++nowr]=a[i];
else zuo[++nowl]=a[i];
}
else{
now=sum(a[i].r)-sum(a[i].l-);//因为操作满足先后顺序,所以不会有影响
if(now>=a[i].val) you[++nowr]=a[i];
else a[i].val-=now,zuo[++nowl]=a[i];
}
}
for(int i=askl;i<=askr;i++) if(a[i].id== && a[i].val>=mid) add(a[i].l,-),add(a[i].r+,); //清空
for(int i=;i<=nowl;i++) a[askl+i-]=zuo[i];
for(int i=;i<=nowr;i++) a[askl+nowl+i-]=you[i];
CDQ(askl,askl+nowl-,l,mid-);
CDQ(askl+nowl,askr,mid,r);
} inline void work(){
n=getint(); m=getint();
for(int i=;i<=m;i++) { a[i].id=getint(); a[i].l=getint(); a[i].r=getint(); a[i].val=getint(); a[i].jilu=i; if(a[i].id==) pd[i]=; }
CDQ(,m,,n);
for(int i=;i<=m;i++) if(pd[i]) printf("%d\n",ans[i]);
} int main()
{
work();
return ;
}

BZOJ 3110 [Zjoi2013]K大数查询的更多相关文章

  1. BZOJ 3110: [Zjoi2013]K大数查询 [树套树]

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

  2. 树套树专题——bzoj 3110: [Zjoi2013] K大数查询 &amp; 3236 [Ahoi2013] 作业 题解

    [原题1] 3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec  Memory Limit: 512 MB Submit: 978  Solved: 476 Descri ...

  3. bzoj 3110: [Zjoi2013]K大数查询 树状数组套线段树

    3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 1384  Solved: 629[Submit][Stat ...

  4. BZOJ 3110: [Zjoi2013]K大数查询( 树状数组套主席树 )

    BIT+(可持久化)权值线段树, 用到了BIT的差分技巧. 时间复杂度O(Nlog^2(N)) ---------------------------------------------------- ...

  5. BZOJ 3110([Zjoi2013]K大数查询-区间第k大[段修改,在线]-树状数组套函数式线段树)

    3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec   Memory Limit: 512 MB Submit: 418   Solved: 235 [ Submit][ ...

  6. BZOJ 3110 [Zjoi2013]K大数查询(整体二分)

    3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 11654  Solved: 3505[Submit][St ...

  7. [BZOJ 3110] [Zjoi2013] K大数查询 【树套树】

    题目链接: BZOJ - 3110 题目分析 这道题是一道树套树的典型题目,我们使用线段树套线段树,一层是区间线段树,一层是权值线段树.一般的思路是外层用区间线段树,内层用权值线段树,但是这样貌似会很 ...

  8. BZOJ 3110 [Zjoi2013]K大数查询 (CDQ分治+树状数组)

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

  9. bzoj 3110 [Zjoi2013]K大数查询——线段树套线段树(标记永久化)

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3110 第一道线段树套线段树! 第一道标记永久化! 为什么为什么写了两个半小时啊…… 本想线段 ...

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

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

随机推荐

  1. AC日记——传话 codevs 1506 (tarjan求环)

    1506 传话  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 白银 Silver 题解       题目描述 Description 一个朋友网络,如果a认识b,那么如果a第 ...

  2. Unity2D Sprite Packer用法介绍

    想充分利用图片空间? 我们用来做sprite的图片通常会留有很多空白的地方,我们在画完了sprite之后,这些地方很可能就没有什么作用了. 如果想避免这些资源上的浪费,我们可以把各个sprite做成图 ...

  3. C# using 三种使用方式 C#中托管与非托管 C#托管资源和非托管资源区别

    1.using指令.using + 命名空间名字,这样可以在程序中直接用命令空间中的类型,而不必指定类型的详细命名空间,类似于Java的import,这个功能也是最常用的,几乎每个cs的程序都会用到. ...

  4. ndk开发教程以及问题解决方案

    一.NDK产生的背景 Android平台从诞生起,就已经支持C.C++开发.众所周知,Android的SDK基于Java实现,这意味着基于Android SDK进行开发的第三方应用都必须使用Java语 ...

  5. 客户端缓存(Client Cache)

    通常在服务器端大家都已经做了很多缓存的工作,ASP.NET CACHE也好MemeryCache也好却总是忽略了客户端缓存. 因为大家都知道不管哪个client都会缓存已经访问过的站点,但是浏览器缓存 ...

  6. C语言 百炼成钢19

    /* 题目55: 有一个字符串符合以下特征(”abcdef,acccd,eeee,aaaa,e3eeeee,sssss,";),要求写一个函数(接口),输出以下结果 1) 以逗号分割字符串, ...

  7. Unity架构有点乱

    1,没有合理的将公共的东西归入到基类中,而是分散到子类中,有许多重复. 比如 enbled的变量本应该是所有component所共有的一个属性,应该写在component.然而却发现并非这样,enbl ...

  8. CAN开发中遇到的奇怪问题

    问题背景: 之前在做USBCAN2开发过程中,遇到一个奇葩问题,当我们加上其中某一句代码时,我们的程序会走不下去,得不到数据,而且在调试的过程中,你也不能暂停,不然,你也得不到数据.后来参考网上一篇帖 ...

  9. [CareerCup] 10.7 Simplified Search Engine 简单的搜索引擎

    10.7 Imagine a web server for a simplified search engine. This system has 100 machines to respond to ...

  10. Android requires compiler compliance level 5.0 or 6.0. Found '1.7' instead. Please use Android Tool

    重装操作系统后,要重新配置Android开发环境.配置成功后,添加原本项目时却出现了错误! Android requires compiler compliance level 5.0 or 6.0. ...