[题目链接]

https://www.lydsy.com/JudgeOnline/problem.php?id=3110

[算法]

整体二分 + 线段树

时间复杂度 : O(NlogN ^ 2)

[代码]

#include<bits/stdc++.h>
using namespace std;
#define MAXN 500010
typedef long long ll;
typedef long double ld; struct query
{
int type , a , b;
ll c;
int id;
} q[MAXN]; int n , m;
int ans[MAXN]; struct Segment_Tree
{
ll cnt[MAXN << ] , tag[MAXN << ];
Segment_Tree()
{
memset(cnt , , sizeof(cnt));
}
inline void pushdown(int index , int l , int r)
{
int mid = (l + r) >> ;
cnt[index << ] += (mid - l + ) * tag[index];
cnt[index << | ] += (r - mid) * tag[index];
tag[index << ] += tag[index];
tag[index << | ] += tag[index];
tag[index] = ;
}
inline void update(int index)
{
cnt[index] = cnt[index << ] + cnt[index << | ];
}
inline void modify(int now , int l , int r , int ql , int qr , int value)
{
if (l == ql && r == qr)
{
cnt[now] += 1ll * value * (qr - ql + );
tag[now] += 1ll * value;
return;
}
pushdown(now , l , r);
int mid = (l + r) >> ;
if (mid >= qr) modify(now << , l , mid , ql , qr , value);
else if (mid + <= ql) modify(now << | , mid + , r , ql , qr , value);
else
{
modify(now << , l , mid , ql , mid , value);
modify(now << | , mid + , r , mid + , qr , value);
}
update(now);
}
inline ll query(int now , int l , int r , int ql , int qr)
{
if (l == ql && r == qr)
return cnt[now];
pushdown(now , l , r);
int mid = (l + r) >> ;
if (mid >= qr) return query(now << , l , mid , ql , qr);
else if (mid + <= ql) return query(now << | , mid + , r , ql , qr);
else return query(now << , l , mid , ql , mid) + query(now << | , mid + , r , mid + , qr);
}
} SGT;
template <typename T> inline void chkmin(T &x , T y) { x = min(x , y); }
template <typename T> inline void chkmax(T &x , T y) { x = max(x , y); }
template <typename T> inline void read(T &x)
{
T f = ; x = ;
char c = getchar();
for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
for (; isdigit(c); c = getchar()) x = (x << ) + (x << ) + c - '';
x *= f;
}
inline void divide(int l , int r , int L , int R)
{
static query tl[MAXN] , tr[MAXN];
int mid = (l + r) >> ;
if (L > R) return;
if (l == r)
{
for (int i = L; i <= R; i++)
if (q[i].type == ) ans[q[i].id] = mid;
return;
} else
{
int pl = , pr = ;
for (int i = L; i <= R; i++)
{
if (q[i].type == )
{
if (q[i].c > mid)
{
tr[++pr] = q[i];
SGT.modify( , , n , q[i].a , q[i].b , );
} else tl[++pl] = q[i];
} else
{
if (SGT.query( , , n , q[i].a , q[i].b) >= q[i].c)
tr[++pr] = q[i];
else
{
q[i].c -= SGT.query( , , n , q[i].a , q[i].b);
tl[++pl] = q[i];
}
}
}
for (int i = L; i <= R; i++)
if (q[i].type == && q[i].c > mid) SGT.modify( , , n , q[i].a , q[i].b , -);
for (int i = L; i <= L + pl - ; i++) q[i] = tl[i - L + ];
for (int i = L + pl; i <= R; i++) q[i] = tr[i - L - pl + ];
divide(l , mid , L , L + pl - );
divide(mid + , r , L + pl , R);
}
} int main()
{ read(n); read(m);
vector< int > que;
for (int i = ; i <= m; i++)
{
read(q[i].type);
read(q[i].a);
read(q[i].b);
read(q[i].c);
q[i].id = i;
if (q[i].type == ) que.push_back(i);
}
divide(-n , n , , m);
for (unsigned i = ; i < que.size(); i++) printf("%d\n" , ans[que[i]]); return ;
}

[ZJOI 2013] K大数查询的更多相关文章

  1. [BZOJ 3110] [luogu 3332] [ZJOI 2013]k大数查询(权值线段树套线段树)

    [BZOJ 3110] [luogu 3332] [ZJOI 2013]k大数查询(权值线段树套线段树) 题面 原题面有点歧义,不过从样例可以看出来真正的意思 有n个位置,每个位置可以看做一个集合. ...

  2. 数据结构(树套树):ZJOI 2013 K大数查询

    有几个点卡常数…… 发现若第一维为位置,第二维为大小,那么修改时第一维修改区间,查询时第一维查询区间,必须挂标记.而这种情况下标记很抽象,而且Push_down不是O(1)的,并不可行. 那要怎么做呢 ...

  3. BZOJ 3110 ZJOI 2013 K大数查询 树套树(权值线段树套区间线段树)

    题目大意:有一些位置.这些位置上能够放若干个数字. 如今有两种操作. 1.在区间l到r上加入一个数字x 2.求出l到r上的第k大的数字是什么 思路:这样的题一看就是树套树,关键是怎么套,怎么写.(话说 ...

  4. [BZOJ 3110] [ZJOI 2013] K大数查询

    Description 有 \(N\) 个位置,\(M\) 个操作.操作有两种,每次操作如果是: 1 a b c:表示在第 \(a\) 个位置到第 \(b\) 个位置,每个位置加入一个数 \(c\): ...

  5. 解题:ZJOI 2013 K大数查询

    题面 树套树,权值线段树套序列线段树,每次在在权值线段树上的每棵子树上做区间加,查询的时候左右子树二分 本来想两个都动态开点的,这样能体现树套树在线的优越性.但是常数太大惹,所以外层直接固定建树了QA ...

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

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

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

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

  8. 区间K 大数查询

      算法训练 区间k大数查询   时间限制:1.0s   内存限制:256.0MB 问题描述 给定一个序列,每次询问序列中第l个数到第r个数中第K大的数是哪个. 输入格式 第一行包含一个数n,表示序列 ...

  9. 蓝桥杯 算法训练 区间k大数查询(水题)

    算法训练 区间k大数查询 时间限制:1.0s   内存限制:256.0MB 问题描述 给定一个序列,每次询问序列中第l个数到第r个数中第K大的数是哪个. 输入格式 第一行包含一个数n,表示序列长度. ...

随机推荐

  1. Node之父ry发布新项目deno:下一代Node

    https://mp.weixin.qq.com/s/1LcO3EqGV2iRlZ1aIrQeqw

  2. 搭建windows下的odoo开发环境

    odoo运行环境的必须要要求是 python环境 postgreSQL数据 数据库可以安装在别的机器上,比如服务器:当然对于开发环境,通常,数据库与代码调试安装在同一台机器上. 首先安装 postgr ...

  3. C# HTTP请求后对gzip页面实现解压缩

    1.通过socket页面请求后的receive内容不能经过string后再进行解压缩处理 会造成错误的gzip幻数报错 推荐使用流处理 2.正确分析返回内容 分割header和页面代码部分 3.对页面 ...

  4. 小胖学PHP总结4-----PHP的字符串操作

    1.字符串连接 字符串是通过半角句号"."来连接的.能够把两个或两个以上的字符串连接成一个字符串. 2.去除字符串首尾空格和特殊字符 PHP中提供了trim()函数去除字符串左右两 ...

  5. C++字符串操作二

    #include <iostream> #include <assert.h> using namespace std; //模拟实现strcmp函数. bool my_str ...

  6. EhCache Monitor的使用

    1.在http://ehcache.org/documentation/monitor.html#Installation_And_Configuration下载ehcache-monitor-kit ...

  7. datatable的使用

    学习可参考:http://www.guoxk.com/node/jquery-datatables http://yuemeiqing2008-163-com.iteye.com/blog/20069 ...

  8. Linux快捷键和vim快捷键

    系统下常用快捷键   ctrl+左右键      在单词之间跳转 Ctrl + a            光标移动到行首(ahead of line),相当于通常的Home键 Ctrl + e     ...

  9. EasyPusher手机直播图像旋转90度后画面重复的问题

    本文转自:http://blog.csdn.net/holo_easydarwin/article/details/51147379 最初在做EasyPusher手机直播的时候遇到过一个问题:手机竖屏 ...

  10. Extjs form 表单的 submit

    说明:extjs form表单的提交方式是多种多样的,本文只是介绍其中的一种方法,本文介绍的方法可能不是完美的,但是对于一般的应用应该是没有问题的.     本文包括的主要内容有:form面板设计.f ...