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

Source

【分析】

我可以吐槽一下数据很水吗?1A了

表示整体二分大法好,离线第K大都不怕。

区间修改用线段树和树状数组都可以水。

 /*
明代杨慎
《临江仙·滚滚长江东逝水》 滚滚长江东逝水,浪花淘尽英雄。
是非成败转头空。
青山依旧在,几度夕阳红。
白发渔樵江渚上,惯看秋月春风。
一壶浊酒喜相逢。
古今多少事,都付笑谈中。
*/
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#include <utility>
#include <iomanip>
#include <string>
#include <cmath>
#include <queue>
#include <assert.h>
#include <map>
#include <ctime>
#include <cstdlib>
#include <stack>
#define LOCAL
const int INF = 0x7fffffff;
const int MAXN = + ;
using namespace std;
//整体二分+树状数组的区间修改!
struct QUESTION{
int l, r;
int k, s, cur, type;
}q[MAXN];
int id[MAXN];
int Max, Min, n, m, Ans[MAXN];
int c[][MAXN];//0是普通和,1是全部和
int tmp[MAXN], q1[MAXN], q2[MAXN], cnt; int lowbit(int x) {return x & -x;}
int sum(int k, int x){
int cnt = ;
while (x > ){
cnt += c[k][x];
x -= lowbit(x);
}
return cnt;
}
void add(int k, int x, int val){
while (x <= n){
c[k][x] += val;
x += lowbit(x);
}
return;
}
//得到一个点真实的前缀和
int get(int x){
if (x == )
printf("");
return sum(, x) - sum(, x) * (n - x);
}
//整体二分
void solve(int l, int r, int L, int R){
if (l > r || L == R) return; int mid = (L + R) >> ;
for (int i = l; i <= r; i++){
//区间加
if (q[id[i]].type == && q[id[i]].k >= mid){//注意是区间第k大
int a = q[id[i]].l, b = q[id[i]].r;
add(, a, );
add(, b + , -);
add(, a, n - a + );
add(, b + , - (n - (b + ) + ));
}else if (q[id[i]].type == ) tmp[id[i]] = get(q[id[i]].r) - get(q[id[i]].l - );
}
//清楚标记
for (int i = l; i <= r; i++){
if (q[id[i]].type == && q[id[i]].k >= mid){
int a = q[id[i]].l, b = q[id[i]].r;
add(, a, -);
add(, b + , );
add(, a, -(n - a + ));
add(, b + , (n - (b + ) + ));
}
}
int l1 = , l2 = ;
//q1放右边,q2放左边
for (int i = l; i <= r; i++){
if (q[id[i]].type == ){
//这个要放在右边
if (q[id[i]].cur + tmp[id[i]] > q[id[i]].k - ){
q1[++l1] = id[i];
Ans[q[id[i]].s] = mid;
}else{
q[id[i]].cur += tmp[id[i]];
q2[++l2] = id[i];
}
}else{
if (q[id[i]].k >= mid) q1[++l1] = id[i];
else q2[++l2] = id[i];
}
} for (int i = ; i <= l2; i++) id[i + l - ] = q2[i];
for (int i = ; i <= l1; i++) id[i + l2 + l - ] = q1[i];
solve(l, l + l2 - , L, mid);
solve(l + l2, r, mid + , R);
}
void init(){
memset(c, , sizeof(c));
scanf("%d%d", &n, &m);
cnt = ;//cnt用来记录询问问题个数
Min = INF, Max = -INF;
for (int i = ; i <= m; i++){
int t;
scanf("%d", &t);
if (t == ){//插入操作
int l, r, x;
scanf("%d%d%d", &l, &r, &x);
q[i].type = ;
q[i].l = l; q[i].r = r;
q[i].k = x; q[i].s = ;
q[i].cur = ;
Max = max(Max, x);
Min = min(Min, x);
}else if (t == ){//询问操作
int l, r, x;
scanf("%d%d%d", &l, &r, &x);
q[i].type = ;
q[i].l = l; q[i].r = r;
q[i].k = x; q[i].cur = ;
q[i].s = ++cnt;//注意这里x是第k大
}
}
for (int i = ; i <= m; i++) id[i] = i;
//printf("%d %d\n", Max, Min);
} int main(){
int T; init();
solve(, m, Min, Max + );
for (int i = ; i <= cnt; i++) printf("%d\n", Ans[i]);
return ;
}

【BZOJ3110】【整体二分+树状数组区间修改/线段树】K大数查询的更多相关文章

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

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

  2. 【bzoj5173】[Jsoi2014]矩形并 扫描线+二维树状数组区间修改区间查询

    题目描述 JYY有N个平面坐标系中的矩形.每一个矩形的底边都平行于X轴,侧边平行于Y轴.第i个矩形的左下角坐标为(Xi,Yi),底边长为Ai,侧边长为Bi.现在JYY打算从这N个矩形中,随机选出两个不 ...

  3. 【bzoj3132】上帝造题的七分钟 二维树状数组区间修改区间查询

    题目描述 “第一分钟,X说,要有矩阵,于是便有了一个里面写满了0的n×m矩阵. 第二分钟,L说,要能修改,于是便有了将左上角为(a,b),右下角为(c,d)的一个矩形区域内的全部数字加上一个值的操作. ...

  4. 【bzoj4540】[Hnoi2016]序列 单调栈+离线+扫描线+树状数组区间修改区间查询

    题目描述 给出一个序列,多次询问一个区间的所有子区间最小值之和. 输入 输入文件的第一行包含两个整数n和q,分别代表序列长度和询问数.接下来一行,包含n个整数,以空格隔开,第i个整数为ai,即序列第i ...

  5. 【bzoj3779】重组病毒 LCT+树上倍增+DFS序+树状数组区间修改区间查询

    题目描述 给出一棵n个节点的树,每一个节点开始有一个互不相同的颜色,初始根节点为1. 定义一次感染为:将指定的一个节点到根的链上的所有节点染成一种新的颜色,代价为这条链上不同颜色的数目. 现有m次操作 ...

  6. 【树状数组区间修改区间求和】codevs 1082 线段树练习 3

    http://codevs.cn/problem/1082/ [AC] #include<bits/stdc++.h> using namespace std; typedef long ...

  7. 【POJ3468】【树状数组区间修改】A Simple Problem with Integers

    Description You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. On ...

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

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

  9. 1082 线段树练习 3 && 树状数组区间修改区间查询

    1082 线段树练习 3 题意: 给定序列初值, 要求支持区间修改, 区间查询 Solution 用树状数组, 代码量小, 空间占用小 巧用增量数组, 修改时在 \(l\) 处 $ + val$ , ...

随机推荐

  1. WIA

    一台扫描仪,实际上就是一个Device对象,因此,我们可以通过DeviceManager来“获取”这台设备的“引用”,然后通过得到的Device对象,执行相应的扫描工作.从而跳过了使用ShowAcqu ...

  2. SQL Server 2005/2008 触发器的管理和查看

    1.通过可视化操作来管理和查看触发器 在Microsoft SQL Server Management Studio中,选中某一数据库的某一张表时,在“对象资源管理器详细”窗口中有“触发器”项.通过“ ...

  3. 深度学习Matlab DeepLearningToolBox 工具包最常见错误解决办法\

    deeplearningtoolbox  下载链接github : https://github.com/rasmusbergpalm/DeepLearnToolbox,只需要解压到matlab当前工 ...

  4. android的生命周期

    1.运行状态:当一个活动处于栈的顶部时,这时活动就处于活动状态,系统是不愿意回收处于活动状态的,会影响用户体验. 2.暂停状态:当一个活动不再处于栈的顶部时,但仍然可见时,这时就是暂停状态了.处于暂停 ...

  5. JDBC基本知识

    JDBC的作用 JDBC为java访问数据库提供通用的API,可以为多种关系数据库提供统一访问.因为SQL是关系式数据库管理系统的标准语言,只要我们遵循SQL规范,那么我们写的代码既可以访问MySQL ...

  6. UIButton图文上下对齐

    - (void)centerImageAndTitle:(float)spacing { // get the size of the elements here for readability CG ...

  7. PullToRefreshListView调用onRefreshComplete方法 无法取消刷新的bug

    我们在使用框架:   PullToRefreshListView 实现下拉或者上拉加载时候,可能在上拉 完成时候,调用onRefreshComplete方法去 停止 刷新操作,但是,可能无效,测试产生 ...

  8. [RxJS] Filtering operators: distinct and distinctUntilChanged

    Operator distinct() and its variants are an important type of Filtering operator. This lessons shows ...

  9. Qt 学习之路 :文件

    文件操作是应用程序必不可少的部分.Qt 作为一个通用开发库,提供了跨平台的文件操作能力.从本章开始,我们来了解下 Qt 的文件以及输入输出的功能,也就是 I/O 系统. Qt 通过QIODevice提 ...

  10. switch-case参数类型

    switch语句用法: 0. switch语句由一个控制表达式和多个case标签组成 1. switch控制表达式支持的类型有byte.short.char.int.enum(JDK5).String ...