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. php strcmp引起的问题

    在官方的文档有这么一端说明: Note a difference between 5.2 and 5.3 versions echo (int)strcmp('pending',array()); w ...

  2. GitHub入门之一:使用github下载项目

    git作为目前比较流行的版本控制系统,被各个互联网公司广泛使用着.目前国外的网站有GitHub,国内的有CSDN和OSCHINA的git. 使用git可以很方便地进行多人协作和版本控制.作为一个入门小 ...

  3. SilverIight数据绑定实例

    前台Code <DataGrid Name="DataGrid1" AutoGenerateColumns="False" IsReadOnly=&quo ...

  4. maven中的 dependencies 和 dependencyManagement 的区别

    今天我在配置 sellercenter 的接口测试环境的时候,发现一些依赖的写法不太一致: 比如有的依赖的<scope>是写在子项目中的 <dependencies> 下的&l ...

  5. Uploadify v3.2.1 属性、事件、方法说明

    一.属性 属性名称 默认值 说明 auto true 设置为true当选择文件后就直接上传了,为false需要点击上传按钮才上传 . buttonClass " 按钮样式 buttonCur ...

  6. js运动框架 step by step

    开启setInterval定时器之前,请先清除之前的定时器 window.onload = function() { var btn = document.getElementById('btn'); ...

  7. 简谈Java的join()方法

    join()是Thread类的一个方法.根据jdk文档的定义: public final void join()throws InterruptedException: Waits for this ...

  8. JS调用Silverlight方法拾遗

    在最近做的物联网项目中,需要利用封装过的Silverlight刻度控件显示温度,湿度,二氧化碳浓度等值.由于最新的数据是通过js ajax获取的,所以需要把这些数据传递给silverlight显示,这 ...

  9. 通过jdbc获取数据库中的表结构

    通过jdbc获取数据库中的表结构 主键 各个表字段类型及应用生成实体类   1.JDBC中通过MetaData来获取具体的表的相关信息.可以查询数据库中的有哪些表,表有哪些字段,字段的属性等等.Met ...

  10. [vim配置]windows下在vim中使用gcc/g++编译调试c/cpp文件

    在Linux里面混了一个多月,vim编程用得甚爽.无奈前天将Linux里面的编程文件夹误删,而技术不精无法找回,悲痛欲绝.再者,无限怀念windows里面的游戏,并觉得现在在Linux里面也学不到什么 ...