题意

有 \(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\) 只有三种情况 .

  1. \(A \subseteq B\) (此时 \(A\) 可以等于 \(B\) ) , \(B\) 完全包含 \(A\) , \(|B| \ge |A|\)
  2. \(A \not \subseteq B\) 且 \(B \not \subseteq A\) , 此时 \(A,B\) 交的部分不会是这两个区间中任意一个全集 .
  3. \(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. 数据结构板子题 (离线+树状数组)的更多相关文章

  1. [LOJ 6270]数据结构板子题

    Description 有n个区间,第i个区间是[li,ri],它的长度是ri−li. 有q个询问,每个询问给定L,R,K,询问被[L,R]包含的且长度不小于K的区间数量. 你想,像这种板子题,你随手 ...

  2. 【细节题 离线 树状数组】luoguP4919 Marisa采蘑菇

    歧义差评:但是和题意理解一样了之后细节依然处理了很久,说明还是水平不够…… 题目描述 Marisa来到了森林之中,看到了一排nn个五颜六色的蘑菇,编号从1-n1−n,这些蘑菇的颜色分别为col[1], ...

  3. 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 ...

  4. [APIO2019] [LOJ 3146] 路灯 (cdq分治或树状数组套线段树)

    [APIO2019] [LOJ 3146] 路灯 (cdq分治或树状数组套线段树) 题面 略 分析 首先把一组询问(x,y)看成二维平面上的一个点,我们想办法用数据结构维护这个二维平面(注意根据题意这 ...

  5. POJ 3416 Crossing --离线+树状数组

    题意: 给一些平面上的点,然后给一些查询(x,y),即以(x,y)为原点建立坐标系,一个人拿走第I,III象限的点,另一个人拿II,IV象限的,点不会在任何一个查询的坐标轴上,问每次两人的点数差为多少 ...

  6. HDU 2852 KiKi's K-Number(离线+树状数组)

    题目链接 省赛训练赛上一题,貌似不难啊.当初,没做出.离线+树状数组+二分. #include <cstdio> #include <cstring> #include < ...

  7. 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 ...

  8. 13年山东省赛 Boring Counting(离线树状数组or主席树+二分or划分树+二分)

    转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud 2224: Boring Counting Time Limit: 3 Sec   ...

  9. 区间的关系的计数 HDU 4638 离线+树状数组

    题目大意:给你n个人,每个人都有一个id,有m个询问,每次询问一个区间[l,r],问该区间内部有多少的id是连续的(单独的也算是一个) 思路:做了那么多离线+树状数组的题目,感觉这种东西就是一个模板了 ...

随机推荐

  1. CF101D Castle 树形DP、贪心

    题目传送门 题意:给出一个有$N$个点的树,你最开始在$1$号点,经过第$i$条边需要花费$w_i$的时间.每条边只能被经过$2$次.求出到达除$1$号点外所有点的最早时间的最小平均值.$N \leq ...

  2. cp 命令有坑

    cp 是个很常用的命令, 基本语法为  cp -v  a   b  把文件a 复制为文件b(-v为显示做了什么,这是非常安全的做法,建议新手添加此参数) 参数说明: -a:此选项通常在复制目录时使用, ...

  3. WD与循环 组合数学

    WD与循环 LG传送门 为什么大家都是先算\(n\)个数的和等于\(m\)的情况再求前缀和? 既然已经想到了插板法,为什么不直接对\(n\)个数的和\(\le m\)的情况做呢? 基本套路没有变:考虑 ...

  4. [尝鲜]妈妈再也不用担心 dotnet core 程序发布了: .NET Core Global Tools

    什么是 .NET Core Global Tools? Global Tools是.NET Core 2.1 中一个初次出现的特性.Global Tools提供了一种方法,让开发人员编写的.NET C ...

  5. spring boot 在不同环境下读取不同配置文件的一种方式

    在工程中,通常有根据不同的环境读取不同配置文件的需求,对于spring boot 来说,默认读取的是application.yml 或者 application.properties.为了区分不同的环 ...

  6. 并行管理工具——pdsh

    1. pdsh安装2. pdsh常规使用2.1 pdsh2.2 pdcp 并行管理的方式有很多种: 命令行 一般是for循环 脚本 一般是expect+ssh等自编辑脚本 工具 pssh,pdsh,m ...

  7. 如何在《救赎之路》中使用CPU粒子效果

    Unreal游戏引擎4.19版本的发布,可以使得游戏可以更好地利用Intel多核心处理器的性能,以提供更精彩的游戏体验.这里以<救赎之路>这款优秀的国产独立游戏为例说明如何在游戏中使用CP ...

  8. ul ol li的序号编号样式

    序号样式例子,下面是html代码(做参考) <ol> <li>列表内容列表内容列表内容列表</li> <li>列表内容列表内容列表内容列表</li ...

  9. 《吃了么》Alpha版本发布说明

    1.功能描述  功能一  查询周边餐厅 选中一条后,会跳转到相应餐厅的网址,获取具体的信息: 功能二 查询指定地点地餐厅 功能三 查询菜谱 具体的菜谱: 还有收藏夹的功能,点击标题栏的心形图标可以将菜 ...

  10. 团队作业 week 14

    0. 在吹牛之前,先回答这个问题: 如果你的团队来了一个新队员,有一台全新的机器, 你们是否有一个文档,只要设置了相应的权限,她就可以根据文档,从头开始搭建环境,并成功地把最新.最稳定版本的软件编译出 ...