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

\(N,M\le50000\)

\(1\) 操作中 \(|c|\le N\)

\(2\) 操作中 \(|c|\le \text{maxlongint}\)

Solution

首先,操作一是给 \([a,b]\) 的每个位置插入一个数 \(c\),每个位置可以有多个数。(我一直以为是区间加QAQ。)

Solve(l, r, L, R) 表示第 \([L,R]\) 个询问可能的答案在区间 \([l,r]\) 中。每次把 \(c\le mid\) 的插入操作放到左边,把 \(c>mid\) 的放到右边;把答案在 \([l,mid]\) 的询问放到左边,把答案在 \([mid+1,r]\) 的询问放到右边。时间复杂度 \(O(n\log^2n)\)。

Code

#include <cstdio>

const int N = 50005;
typedef long long LL;
struct Node { int l, r, x, f; LL k; } a[N], b[N], c[N];
int ans[N], n, m, cnt; LL tag[N << 3], sum[N << 3]; int read() {
int x = 0, f = 1; char c = getchar();
while (c < '0' || c > '9') { if (c == '-') f = -1; c = getchar(); }
while (c >= '0' && c <= '9') x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
return x * f;
}
void pushdown(int cur, int l, int r) {
int mid = (l + r) >> 1;
tag[cur << 1] += tag[cur], tag[cur << 1 | 1] += tag[cur];
sum[cur << 1] += tag[cur] * (mid - l + 1), sum[cur << 1 | 1] += tag[cur] * (r - mid);
tag[cur] = 0;
}
void update(int cur, int l, int r, int L, int R, int x) {
if (L <= l && r <= R) { tag[cur] += x, sum[cur] += x * (r - l + 1); return; }
if (tag[cur]) pushdown(cur, l, r);
int mid = (l + r) >> 1;
if (L <= mid) update(cur << 1, l, mid, L, R, x);
if (mid < R) update(cur << 1 | 1, mid + 1, r, L, R, x);
sum[cur] = sum[cur << 1] + sum[cur << 1 | 1];
}
LL query(int cur, int l, int r, int L, int R) {
if (L <= l && r <= R) return sum[cur];
if (tag[cur]) pushdown(cur, l, r);
int mid = (l + r) >> 1; LL res = 0;
if (L <= mid) res = query(cur << 1, l, mid, L, R);
if (mid < R) res += query(cur << 1 | 1, mid + 1, r, L, R);
return res;
}
void solve(int l, int r, int L, int R) {
if (l > r || L > R) return;
if (l == r) {
for (int i = L; i <= R; ++i) if (a[i].f) ans[a[i].x] = n - l + 1;
return;
}
int mid = (l + r) >> 1, p = 0, q = 0;
for (int i = L; i <= R; ++i)
if (a[i].f) {
LL tmp = query(1, 1, n, a[i].l, a[i].r);
if (tmp >= a[i].k) b[++p] = a[i];
else a[i].k -= tmp, c[++q] = a[i];
} else {
if (a[i].k <= mid) update(1, 1, n, a[i].l, a[i].r, 1), b[++p] = a[i];
else c[++q] = a[i];
}
for (int i = 1; i <= p; ++i) if (!b[i].f) update(1, 1, n, b[i].l, b[i].r, -1);
for (int i = 1; i <= p; ++i) a[L + i - 1] = b[i];
for (int i = 1; i <= q; ++i) a[L + p + i - 1] = c[i];
solve(l, mid, L, L + p - 1), solve(mid + 1, r, L + p, R);
}
int main() {
n = read(), m = read();
for (int i = 1; i <= m; ++i) {
int op = read(), x = read(), y = read(); LL z; scanf("%lld", &z);
if (op == 1) a[i] = (Node){x, y, i, 0, n - z + 1};
else a[i] = (Node){x, y, ++cnt, 1, z};
}
solve(1, n, 1, m);
for (int i = 1; i <= cnt; ++i) printf("%d\n", ans[i]);
return 0;
}

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

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

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

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

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

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

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

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

    http://www.lydsy.com/JudgeOnline/problem.php?id=3110 题意:-- 思路:其实和之前POJ那道题差不多,只不过是换成区间更新,而且是第k大不是第k小, ...

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

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

  6. [ZJOI 2013] K大数查询

    [题目链接] https://www.lydsy.com/JudgeOnline/problem.php?id=3110 [算法] 整体二分 + 线段树 时间复杂度 : O(NlogN ^ 2) [代 ...

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

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

  8. 【bzoj 3110】[Zjoi2013]K大数查询

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

  9. 【34.14%】【BZOJ 3110】 [Zjoi2013]K大数查询

    Time Limit: 20 Sec Memory Limit: 512 MB Submit: 5375 Solved: 1835 [Submit][Status][Discuss] Descript ...

随机推荐

  1. css中关于table的相关设置

    一.设置好看的单边框表格 1.一种实现方式 分别给table标签和td标签设置不在同一方向的border属性,如下table设置‘左上’边框,td设置‘右下’边框.其他设置方式同样可以实现. tabl ...

  2. 卷烟厂生产管理系统基于ASP.NET

    VS.Net 2003开发的一个非常老的生产信息管理系统运行10多年依旧稳定,这几天来南昌做维保工作,看到了曾经开发的信息系统.该系统在我眼里老到几点,可却依然在厂里大面积使用,抛开技术上的落后,从新 ...

  3. 如何程序化的构造Hibernate配置 // How to initialize Hibernate programmably

    Java为什么被人诟病,因为一切都是过度设计.Hibernate其实就是实现了一套JPA的ORM,不过用极度冗赘的配置方式,nodejs Sequelize.js,甚至Python SQLAlchem ...

  4. 章节八、2-火狐的插件TryXPath

    一.火狐上有一个很好用的插件TryXPath能够进行元素定位(安装) 1.打开图中标识的菜单 2.然后点击“扩展”,搜索“xpath” 3.然后安装“TryXPath” 4.安装成功后右上角x显示一个 ...

  5. 全民抵制“辱华”品牌秀,D&G神回复:呵呵~ 那不是我!

    ### 补发一下,前写天写的: 就在今天下午,有网友爆出知名品牌 Dolce&Gabbana(杜嘉班纳)的设计师兼创始人Stefano Gabbana在ins上公然发表辱华言论. 下面截图 可 ...

  6. 关于Docker开通远程访问端口2375

    一.使用版本:docker for windows 18.06,安装过程略,具体如下: 二.开通远程访问端口2375,只需要设置一下即可,如下图:

  7. 转://linux下的CPU、内存、IO、网络的压力测试工具与方法介绍

    转载地址:http://wushank.blog.51cto.com/3489095/1585927 一.对CPU进行简单测试: 1.通过bc命令计算特别函数 例:计算圆周率 echo "s ...

  8. 【转】从源码分析Handler的postDelayed为什么可以延时?

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/aliankg/article/details/70842494Thread/Hander/Loope ...

  9. python之pickle

    #!/usr/bin/python # -*- coding: UTF- -*- ''' ''' import pickle # pickle 只能Python识别 不适用于别的语言 li = [, ...

  10. Struts2的核心——拦截器

    虽然以前已经学了很多的拦截器,但是在这里还是想重头梳理一下所有有关拦截器的知识,尤其是struts2中的拦截器 1:拦截器是什么? java里的拦截器是动态拦截Action调用的对象.它提供了一种机制 ...