[ZJOI 2013] K大数查询
[题目链接]
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大数查询的更多相关文章
- [BZOJ 3110] [luogu 3332] [ZJOI 2013]k大数查询(权值线段树套线段树)
[BZOJ 3110] [luogu 3332] [ZJOI 2013]k大数查询(权值线段树套线段树) 题面 原题面有点歧义,不过从样例可以看出来真正的意思 有n个位置,每个位置可以看做一个集合. ...
- 数据结构(树套树):ZJOI 2013 K大数查询
有几个点卡常数…… 发现若第一维为位置,第二维为大小,那么修改时第一维修改区间,查询时第一维查询区间,必须挂标记.而这种情况下标记很抽象,而且Push_down不是O(1)的,并不可行. 那要怎么做呢 ...
- BZOJ 3110 ZJOI 2013 K大数查询 树套树(权值线段树套区间线段树)
题目大意:有一些位置.这些位置上能够放若干个数字. 如今有两种操作. 1.在区间l到r上加入一个数字x 2.求出l到r上的第k大的数字是什么 思路:这样的题一看就是树套树,关键是怎么套,怎么写.(话说 ...
- [BZOJ 3110] [ZJOI 2013] K大数查询
Description 有 \(N\) 个位置,\(M\) 个操作.操作有两种,每次操作如果是: 1 a b c:表示在第 \(a\) 个位置到第 \(b\) 个位置,每个位置加入一个数 \(c\): ...
- 解题:ZJOI 2013 K大数查询
题面 树套树,权值线段树套序列线段树,每次在在权值线段树上的每棵子树上做区间加,查询的时候左右子树二分 本来想两个都动态开点的,这样能体现树套树在线的优越性.但是常数太大惹,所以外层直接固定建树了QA ...
- 树套树专题——bzoj 3110: [Zjoi2013] K大数查询 & 3236 [Ahoi2013] 作业 题解
[原题1] 3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec Memory Limit: 512 MB Submit: 978 Solved: 476 Descri ...
- BZOJ 3110: [Zjoi2013]K大数查询 [树套树]
3110: [Zjoi2013]K大数查询 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 6050 Solved: 2007[Submit][Sta ...
- 区间K 大数查询
算法训练 区间k大数查询 时间限制:1.0s 内存限制:256.0MB 问题描述 给定一个序列,每次询问序列中第l个数到第r个数中第K大的数是哪个. 输入格式 第一行包含一个数n,表示序列 ...
- 蓝桥杯 算法训练 区间k大数查询(水题)
算法训练 区间k大数查询 时间限制:1.0s 内存限制:256.0MB 问题描述 给定一个序列,每次询问序列中第l个数到第r个数中第K大的数是哪个. 输入格式 第一行包含一个数n,表示序列长度. ...
随机推荐
- MFC office2007风格设置左侧导航栏 [转]
当基础的框架搭好以后,我想为其添加一个左侧导航栏,过程如下:在框架类的头文件添加一个导航栏参数: CMFCOutlookBar m_navigation; 为了完善功能,在导航栏里面我添加了一个CTr ...
- 基于ACCESS和ASP的SQL多个表查询与计算统计代码(一)
近期在写几个关于"Project - Subitem - Task"的管理系统,说是系统还是有点夸大了,基本就是一个多表查询调用和insert.update的数据库操作.仅仅是出现 ...
- angular - 使用es6等一些功能
app.module.ts var model = { user: 'Admin', items: [{ action: 'buy flowsers', done: false },{ action: ...
- iOS开发 — (UINaVigationController)导航控制器,界面传值
UINavigationController 继承于 UIViewController , 以栈的方式管理所 控制的视图控制器 . 至少要有一个被管理的视图控制器 ,这个控制器我们称作导航控制器的根视 ...
- JSP技术基础(动态网页基础)
前言:如果说html为静态网页基础,那么jsp就是动态网页基础,两者的区别就是jsp在html的前面多加了几行而已.当然,jsp里面对java的支持度更高.要明白,js只是嵌入在客户端的小程序小脚本而 ...
- CUDA编程->CUDA入门了解(一)
安装好CUDA6.5+VS2012,操作系统为Win8.1版本号,首先下个GPU-Z检測了一下: 看出本显卡属于中低端配置.关键看两个: Shaders=384.也称作SM.或者说core/流处理器数 ...
- mysql 修改表引擎方法
修改表引擎方法 方法1:修改mysql.ini配置文件,重启mysql服务生效 修改my.ini,在[mysqld]下加上default-storage-engine=INNODB 其中红色字体部分是 ...
- 【转载】Web Service和WCF的到底有什么区别
[1]Web Service:严格来说是行业标准,也就是Web Service 规范,也称作WS-*规范,既不是框架,也不是技术. 它有一套完成的规范体系标准,而且在持续不断的更新完善中. 它使用XM ...
- C中參数个数可变的函数
一.什么是可变參数 我们在C语言编程中有时会遇到一些參数个数可变的函数,比如printf()函数,其函数原型为: int printf( const char* format, ...); 它除了有一 ...
- LeetCode120——Triangle
Given a triangle, find the minimum path sum from top to bottom. Each step you may move to adjacent n ...