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是连续的(单独的也算是一个) 思路:做了那么多离线+树状数组的题目,感觉这种东西就是一个模板了 ...
随机推荐
- CF101D Castle 树形DP、贪心
题目传送门 题意:给出一个有$N$个点的树,你最开始在$1$号点,经过第$i$条边需要花费$w_i$的时间.每条边只能被经过$2$次.求出到达除$1$号点外所有点的最早时间的最小平均值.$N \leq ...
- cp 命令有坑
cp 是个很常用的命令, 基本语法为 cp -v a b 把文件a 复制为文件b(-v为显示做了什么,这是非常安全的做法,建议新手添加此参数) 参数说明: -a:此选项通常在复制目录时使用, ...
- WD与循环 组合数学
WD与循环 LG传送门 为什么大家都是先算\(n\)个数的和等于\(m\)的情况再求前缀和? 既然已经想到了插板法,为什么不直接对\(n\)个数的和\(\le m\)的情况做呢? 基本套路没有变:考虑 ...
- [尝鲜]妈妈再也不用担心 dotnet core 程序发布了: .NET Core Global Tools
什么是 .NET Core Global Tools? Global Tools是.NET Core 2.1 中一个初次出现的特性.Global Tools提供了一种方法,让开发人员编写的.NET C ...
- spring boot 在不同环境下读取不同配置文件的一种方式
在工程中,通常有根据不同的环境读取不同配置文件的需求,对于spring boot 来说,默认读取的是application.yml 或者 application.properties.为了区分不同的环 ...
- 并行管理工具——pdsh
1. pdsh安装2. pdsh常规使用2.1 pdsh2.2 pdcp 并行管理的方式有很多种: 命令行 一般是for循环 脚本 一般是expect+ssh等自编辑脚本 工具 pssh,pdsh,m ...
- 如何在《救赎之路》中使用CPU粒子效果
Unreal游戏引擎4.19版本的发布,可以使得游戏可以更好地利用Intel多核心处理器的性能,以提供更精彩的游戏体验.这里以<救赎之路>这款优秀的国产独立游戏为例说明如何在游戏中使用CP ...
- ul ol li的序号编号样式
序号样式例子,下面是html代码(做参考) <ol> <li>列表内容列表内容列表内容列表</li> <li>列表内容列表内容列表内容列表</li ...
- 《吃了么》Alpha版本发布说明
1.功能描述 功能一 查询周边餐厅 选中一条后,会跳转到相应餐厅的网址,获取具体的信息: 功能二 查询指定地点地餐厅 功能三 查询菜谱 具体的菜谱: 还有收藏夹的功能,点击标题栏的心形图标可以将菜 ...
- 团队作业 week 14
0. 在吹牛之前,先回答这个问题: 如果你的团队来了一个新队员,有一台全新的机器, 你们是否有一个文档,只要设置了相应的权限,她就可以根据文档,从头开始搭建环境,并成功地把最新.最稳定版本的软件编译出 ...