LOJ #6270. 数据结构板子题 (离线+树状数组)
题意
有 \(n\) 个区间,第 \(i\) 个区间是 \([l_i,r_i]\) ,它的长度是 \(r_i-l_i\) 。
有 \(q\) 个询问,每个询问给定 \(L,R,K\) ,询问被 \([L,R]\) 包含的且长度不小于 \(K\) 的区间数量。
\(n,q≤500,000\)
题解
想了无数种 \(O((n+q) \log^2 n)\) 的做法啊TAT 后来看了 这份代码 后恍然大悟 .
这题一个很显然的想法是离线 qwq
首先离线 \(l ~or~ r\) 似乎不太可行 , 因为要动态支持查找一个区间 \([L, R]\) 不小于 \(K\) 的个数 , 而主席树需要离线完成 (划分树没学过 , 不知道可不可以) 在线的话只有 \(O(\log^2)\) 的复杂度可行了 .
那继续考虑离线 \(K\) , 然后这样的话 , 我们就可以忽略 \(K\) 的限制 .
假设我们当前算出了对于一个询问 所有长度 \(\le k\) 的区间个数 \(res_k\) , 那这个答案就可以表示成 \(res_n - res_{K-1}\) .
我们此时只需要做的就是 计算一个区间包含了当前的多少个区间 .
这个如何做呢 qwq
两个区间 \(A, B\) 只有三种情况 .
- \(A \subseteq B\) (此时 \(A\) 可以等于 \(B\) ) , \(B\) 完全包含 \(A\) , \(|B| \ge |A|\)
- \(A \not \subseteq B\) 且 \(B \not \subseteq A\) , 此时 \(A,B\) 交的部分不会是这两个区间中任意一个全集 .
- \(B \subseteq A ~(A\not = B)\) , \(A\) 完全包含 \(B\) , \(|A| > |B|\)
我们假设前面插入的区间为 \(A\) , 当前询问的区间为 \(B\) . 我们计算的就只有第 \(1\) 种情况了 .
不难发现 第 \(3\) 情况计数很麻烦 .
我们最好忽略第 \(3\) 种情况 , 只计算第 \(2\) 种情况 . (因为这个 \(A\) 会有两个出去不好计算)
不难发现长度会有限制 , 那我们询问的时候 只要询问所有 \(len \le R - L\) 的区间就行了 , 也就是每个离线后变成计算 \(res_{R-L} - res_{K - 1}\) .
而对于第 \(2\) 种情况 , \(A\) 只有一端会超出 \(B\) .
然后每次询问 \(res_i\) 的时候 假设当前插入的线段的总数是 \(tot\) .
答案显然就是 $tot - $ 前面左端点存在于 \([1, L - 1]\) 的线段个数 - 前面右端点存在于 \([R + 1, n]\) 的线段个数 .
(可以发现 , 这样很好地处理了两个线段相离的情况)
然后这个用两个树状数组统计一下 , 左端点和右端点各一个 .
所以最后的时间复杂度就是 \(O((n + q) \log n)\) 了 .
注意一开始离线的时候 要特判掉 \(R-L < K\) 的情况 !!
最好自己画图理解 , 博主懒就没放上来了qwq
代码
#include <bits/stdc++.h>
#define For(i, l, r) for(register int i = (l), i##end = (int)(r); i <= i##end; ++i)
#define Fordown(i, r, l) for(register int i = (r), i##end = (int)(l); i >= i##end; --i)
#define Set(a, v) memset(a, v, sizeof(a))
#define debug(x) cout << #x << ':' << x << endl
using namespace std;
inline bool chkmin(int &a, int b) {return b < a ? a = b, 1 : 0;}
inline bool chkmax(int &a, int b) {return b > a ? a = b, 1 : 0;}
inline int read() {
int x = 0, fh = 1; char ch = getchar();
for (; !isdigit(ch); ch = getchar()) if (ch == '-') fh = -1;
for (; isdigit(ch); ch = getchar()) x = (x << 1) + (x << 3) + (ch ^ 48);
return x * fh;
}
void File() {
#ifdef zjp_shadow
freopen ("6270.in", "r", stdin);
freopen ("6270.out", "w", stdout);
#endif
}
const int N = 500100;
int n, q;
#define lowbit(x) (x & -x)
struct Fenwick_Tree {
int sumv[N];
inline void Update(int pos) { for(; pos <= n; pos += lowbit(pos)) ++ sumv[pos]; }
inline int Query(int pos) { int res = 0; for (; pos > 0; pos ^= lowbit(pos)) res += sumv[pos]; return res; }
} Pre, Suf;
struct Ask { int opt, l, r, id; } ;
typedef pair<int, int> PII;
#define fir first
#define sec second
vector<Ask> Q[N]; vector<PII> V[N]; int ans[N];
#define Rev(x) (n - (x) + 1)
int main () {
File();
n = read(); q = read();
For (i, 1, n) {
int l = read(), r = read(), len = r - l;
V[len].push_back(make_pair(l, r));
}
For (i, 1, q) {
int l = read(), r = read(), k = read(), len = r - l;
if (len >= k)
Q[k - 1].push_back((Ask) {-1, l, r, i}),
Q[len].push_back((Ask) {1, l, r, i});
}
int tot = 0;
For (i, 1, n) {
for (PII Up : V[i])
Pre.Update(Up.fir), Suf.Update(Rev(Up.sec)), ++ tot;
for (Ask Rp : Q[i])
ans[Rp.id] += Rp.opt * (tot - Pre.Query(Rp.l - 1) - Suf.Query(Rev(Rp.r + 1)));
}
For (i, 1, q) printf ("%d\n", ans[i]);
return 0;
}
LOJ #6270. 数据结构板子题 (离线+树状数组)的更多相关文章
- [LOJ 6270]数据结构板子题
Description 有n个区间,第i个区间是[li,ri],它的长度是ri−li. 有q个询问,每个询问给定L,R,K,询问被[L,R]包含的且长度不小于K的区间数量. 你想,像这种板子题,你随手 ...
- 【细节题 离线 树状数组】luoguP4919 Marisa采蘑菇
歧义差评:但是和题意理解一样了之后细节依然处理了很久,说明还是水平不够…… 题目描述 Marisa来到了森林之中,看到了一排nn个五颜六色的蘑菇,编号从1-n1−n,这些蘑菇的颜色分别为col[1], ...
- SPOJ DQUERY - D-query (莫队算法|主席树|离线树状数组)
DQUERY - D-query Given a sequence of n numbers a1, a2, ..., an and a number of d-queries. A d-query ...
- [APIO2019] [LOJ 3146] 路灯 (cdq分治或树状数组套线段树)
[APIO2019] [LOJ 3146] 路灯 (cdq分治或树状数组套线段树) 题面 略 分析 首先把一组询问(x,y)看成二维平面上的一个点,我们想办法用数据结构维护这个二维平面(注意根据题意这 ...
- POJ 3416 Crossing --离线+树状数组
题意: 给一些平面上的点,然后给一些查询(x,y),即以(x,y)为原点建立坐标系,一个人拿走第I,III象限的点,另一个人拿II,IV象限的,点不会在任何一个查询的坐标轴上,问每次两人的点数差为多少 ...
- HDU 2852 KiKi's K-Number(离线+树状数组)
题目链接 省赛训练赛上一题,貌似不难啊.当初,没做出.离线+树状数组+二分. #include <cstdio> #include <cstring> #include < ...
- CF #365 (Div. 2) D - Mishka and Interesting sum 离线树状数组(转)
转载自:http://www.cnblogs.com/icode-girl/p/5744409.html 题目链接:CF #365 (Div. 2) D - Mishka and Interestin ...
- 13年山东省赛 Boring Counting(离线树状数组or主席树+二分or划分树+二分)
转载请注明出处: http://www.cnblogs.com/fraud/ ——by fraud 2224: Boring Counting Time Limit: 3 Sec ...
- 区间的关系的计数 HDU 4638 离线+树状数组
题目大意:给你n个人,每个人都有一个id,有m个询问,每次询问一个区间[l,r],问该区间内部有多少的id是连续的(单独的也算是一个) 思路:做了那么多离线+树状数组的题目,感觉这种东西就是一个模板了 ...
随机推荐
- IDM 破解
IDM确实好用,现贴出破解教程. 感谢原文作者:https://jingyan.baidu.com/article/11c17a2c2bd026f447e39d5a.html
- 4.5《想成为黑客,不知道这些命令行可不行》(Learn Enough Command Line to Be Dangerous)—第四章小结
本章相关重要命令总结在Table 6. 命令 描述 示例 mkdir <name> 创建某目录 $ mkdir foo pwd 显示当前所在目录 $ pwd cd <dir> ...
- LiveCharts文档-4基本绘图-3其他
原文:LiveCharts文档-4基本绘图-3其他 4基本绘图-3其他 因为每个图表的使用方法大同小异,所以不再啰嗦重复,具体直接看这个链接里的介绍.原文链接 其他的图表类型有 基本堆叠图 基本条形图 ...
- 算法相关——Java排序算法之冒泡排序(二)
0. 前言 本系列文章将介绍一些常用的排序算法.排序是一个非常常见的应用场景,也是开发岗位面试必问的一道面试题,有人说,如果一个企业招聘开发人员的题目中没有排序算法题,那说明这个企业不是一个" ...
- 在平衡树的海洋中畅游(四)——FHQ Treap
Preface 关于那些比较基础的平衡树我想我之前已经介绍的已经挺多了. 但是像Treap,Splay这样的旋转平衡树码亮太大,而像替罪羊树这样的重量平衡树却没有什么实际意义. 然而类似于SBT,AV ...
- [Spark][python]以DataFrame方式打开Json文件的例子
[Spark][python]以DataFrame方式打开Json文件的例子: [training@localhost ~]$ cat people.json{"name":&qu ...
- 限流——spring-cloud-zuul-ratelimit
先留个坑,慢慢补 git代码Demo:https://github.com/islowcity/spring-cloud-zuul-ratelimiter.git 有时间再写分析
- .NetCore实践篇:分布式监控Zipkin持久化之殇
前言 本系列已写了四篇文章,读本篇之前,可以先读前面几篇. 思考大纲:.Net架构篇:思考如何设计一款实用的分布式监控系统? 实践篇一:.NetCore实践篇:分布式监控客户端ZipkinTracer ...
- 【已解决】HeidiSQL连接(登录)MySQL数据库报错10061问题
解决方法: 打开cmd->输入命令services.msc 然后打开即可解决.
- OpenTK教程-1绘制一个三角形
OpenTK的官方文档是真心的少,他们把怎么去安装OpenTK说的很清楚,但是也就仅限于此,这有一篇learn opentk in 15的教程(链接已经失效,译者注),但是并不完美.你可以在15分钟内 ...