题意

有 \(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. Opencv 2.4.10 +VS2010 项目配置

    资料来源:http://blog.csdn.net/scottly1/article/details/40978625

  2. CSS 字体(font)实例

    CSS 字体(font)实例CSS 字体属性定义文本的字体系列.大小.加粗.风格(如斜体)和变形(如小型大写字母).CSS 字体系列在 CSS 中,有两种不同类型的字体系列名称: 通用字体系列 - 拥 ...

  3. Webpack 2 视频教程 004 - Webpack 初体验

    原文发表于我的技术博客 这是我免费发布的高质量超清「Webpack 2 视频教程」. Webpack 作为目前前端开发必备的框架,Webpack 发布了 2.0 版本,此视频就是基于 2.0 的版本讲 ...

  4. C#爬虫基本知识

    url编码解码 首先引用程序集System.Web.dll 如果要解码某个url的参数值的话,可以调用下面的方法: System.Web.HttpUtility.UrlDecode(string) 对 ...

  5. 利用Tarjan算法解决(LCA)二叉搜索树的最近公共祖先问题——数据结构

    相关知识:(来自百度百科)  LCA(Least Common Ancestors) 即最近公共祖先,是指在有根树中,找出某两个结点u和v最近的公共祖先. 例如: 1和7的最近公共祖先为5: 1和5的 ...

  6. iptables限制连接数(如sftp) 以及 谨防CC/DDOS攻击的配置 ( connlimit模块)

    之前在公司服务器上部署了sftp,用于上传业务系统的附件.后来由于程序连接问题,使的sftp连接数过多(最多时高达400多个sftp连接数),因为急需要对sftp的连接数做严格限制.操作记录如下: 启 ...

  7. [BUAA软工]第一次结对作业

    [BUAA软工]结对作业 本次作业所属课程: 2019BUAA软件工程 本次作业要求: 结对项目 我在本课程的目标: 熟悉结对合作,为团队合作打下基础 本次作业的帮助:理解一个c++ 项目的开发历程 ...

  8. 运行scrapy crawl (文件名)时显示invalid syntax和no modle 'win32api'解决方案

    使用pycharm爬取知乎网站的时候,在terminal端输入scarpy crawl zhihu,提示语法错误,如下: 原因是python3.7中将async设为关键字,根据错误提示,找到manho ...

  9. spring mvc的工作原理

    该文转载自:http://blog.csdn.net/u012191627/article/details/41943393 SpringMVC框架介绍 1) spring MVC属于SpringFr ...

  10. 2017[BUAA软工]第0次个人作业

    第一部分:结缘计算机 1.你为什么选择计算机专业?你认为你的条件如何?和这些博主比呢? ●其实填写志愿之前并不知道要学什么专业,当初选择计算机是因为计算机就业前景好.方向多.计算机应用的领域无处不在, ...