Time Limit: 20 Sec Memory Limit: 512 MB

Submit: 5375 Solved: 1835

[Submit][Status][Discuss]

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

【题解】



树套树。一个权值的线段树套一个区间的线段树。

比如[4,6]这个权值范围->第一层

我们就在第二层里面获得在所有的区间[l,r]内有多少个在[4,6]范围内的数。

即权值范围为[be,en],然后求出在任意的[l,r]内有多少个权值范围在[be,en]内的数。

最后二分获取答案即可。

二分的时候枚举答案;

获取中点m=(l+r)>>1;

看看在m+1..r这个权值范围内,且区间在【L,R】的数字有多少个;

然后做相应的事情

看代码吧

#include <cstdio>

const int MAXN = 50000+100;
const int MAXM = MAXN * 16 * 16; int n, m,L,R,c;
int root[MAXN<<2] = { 0 },cnt,lc[MAXM],rc[MAXM];
long long sum[MAXM],lz[MAXM]; void modify(int &rt, int begin, int end)
{
if (!rt)
rt = ++cnt;
if (L <= begin && end <= R)
{
sum[rt] += end - begin + 1;
lz[rt] ++;
return;
}
int m = (begin + end) >> 1;
if (L <= m)
modify(lc[rt], begin, m);
if (m < R)
modify(rc[rt], m + 1, end);
sum[rt] = sum[lc[rt]] + sum[rc[rt]] + lz[rt] * (end - begin + 1);
} void up_data()
{
int l = 1, r = n, now = 1;//now代表的是l..r这个权值范围所代表的第二层线段树的根节点
while (l != r)
{
int m = (l + r) >> 1;
modify(root[now], 1, n);//虽然修改的是部分区间,但是整个大区间都会变化
//即now这个根节点所代表的权值区间,它的二层范围区间内的数字的个数会发生变化
if (c <= m)
r = m, now <<= 1;
else
l = m + 1, now = now << 1 | 1;
}
modify(root[now], 1, n);
} int min(int a, int b)
{
return a > b ? b : a;
} int max(int a, int b)
{
return a > b ? a : b;
} long long cal(int rt, int begin, int end)
{
if (!rt)
return 0;
if (L <= begin && end <= R)
return sum[rt];
long long temp1 = 0, temp2 = 0;
int m = (begin + end) >> 1;
if (L <= m)
temp1 = cal(lc[rt], begin, m);
if (m < R)
temp2 = cal(rc[rt], m + 1, end);
return temp1 + temp2 + lz[rt] * (min(end, R) - max(L, begin)+1);
} int query()
{
int l = 1, r = n, now = 1;
while (l != r)
{
int m = (l + r) >> 1;
long long temp = cal(root[now << 1|1], 1, n);//计算比m大的数有多少个.(满足在【L,R】区间)
if (c <= temp)
l = m + 1, now = now << 1 | 1;
else//c>temp
r = m, now = now << 1, c -= temp;
}
return l;
} int main()
{
//freopen("F:\\rush.txt", "r", stdin);
scanf("%d%d", &n, &m);
int opt;
for (int i = 1; i <= m; i++)
{
scanf("%d%d%d%d", &opt, &L, &R, &c);
if (opt == 1)
up_data();
else
printf("%d\n", query());
}
return 0;
}

【34.14%】【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. 使用wget工具抓取网页和图片 及 相关工具几个

    想保存一些网页,最后找到这 wget 的 shell脚本,虽然不是太理想,亲测可用呢. 使用wget工具抓取网页和图片   来源 https://my.oschina.net/freestyletim ...

  2. zendiscovery 的Ping机制

    ping是集群发现的基本手段,通过在网络上广播或者指定ping某些节点获取集群信息,从而可以找到集群的master加入集群.zenDiscovery实现了两种凭机制:广播与单播.本篇将详细分析一些这M ...

  3. ELKstack 中文指南

    https://www.elastic.co/downloads ELKstack 中文指南 .net Elasticsearch 学习入门笔记   一. es安装相关1.elasticsearch安 ...

  4. Spider_lxml

    xpath工具(解析) xpath 在XML文档中查找信息的语言,同样适用于HTML文档的检索 xpath辅助工具 Chrome插件 :XPath Helper 打开 :Ctrl + Shift + ...

  5. vector转数组

    vector转数组 由于vector内部的数据是存放在连续的存储空间,vector转数组事实上只需要获取vector中第一个数据的地址和数据的长度即可.如果仅仅是传参,无需任何操作,直接传地址即可,如 ...

  6. CISP/CISA 每日一题 14

    CISA 每日一题(答) 自动无人值守运行(LIGHTS-OUT)优势:1.信息系统运行成本的遏制/减少:2.持续运行(24/7):3.减少系统错误和中断次数. I/O 控制人员负责保证:1.批处理信 ...

  7. Activity学习

    http://www.360doc.com/content/13/1106/11/203871_327110236.shtml http://www.jianshu.com/p/e6971e8a8da ...

  8. Spark 概念学习系列之Spark存储管理机制

    Spark存储管理机制 概要 01 存储管理概述 02 RDD持久化 03 Shuffle数据存储 04 广播变量与累加器 01 存储管理概述 思考: RDD,我们可以直接使用而无须关心它的实现细节, ...

  9. 分析器错误消息: 此实现不是 Windows 平台 FIPS 验证的加密算法的一部分

    关于错误提示:此实现不是 Windows 平台 FIPS 验证的加密算法的一部分的解决方案 不知怎么的,每次Win10升级后相应的注册器都恢复默认了,当我运行08版的asp项目时会报这个错. vs上的 ...

  10. Linux常用运维命令小结

    1. 空设备文件以及标准输入输出 /dev/null 表示空设备文件 0 表示stdin标准输入 1 表示stdout标准输出 2 表示stderr标准错误 2>&1 这里有两种解释:将 ...