题意:给定n个区间,每个区间有颜色。m次询问,每次询问:这n个区间中所有被包含在[x, y]这一区间中的区间,它们的颜色是否取遍了[l, r]中的所有颜色。

强制在线。

解:第一步是大家都熟悉的套路⑧,把这些区间按照左端点排序。

然后从右往左加区间,用一个可持久化数据结构维护答案。

然后我在这里就被套路住了......一般来说是线段树上x维护右端点为x的答案。但是本题要把第二维换一下。

主席树的版本仍旧是左端点。但是线段树上每个位置维护的是该颜色的区间,结尾的最小值。

然后查询,我们就查对应版本对应颜色区间的全体最大值是否大于y。大于y表示那个颜色无解。输出no。否则输出yes。

 #include <bits/stdc++.h>

 const int N = , M = , INF = 0x7f7f7f7f;

 struct Node {
int l, r, c;
inline bool operator <(const Node &w) const {
return l < w.l;
}
}node[N]; int ls[M], rs[M], large[M], tot;
int xx, q, n, lm, X[N], rt[N]; void insert(int &x, int y, int p, int v, int l, int r) {
if(!x || x == y) {
x = ++tot;
ls[x] = ls[y];
rs[x] = rs[y];
large[x] = large[y];
}
if(l == r) {
large[x] = std::min(large[x], v);
return;
}
int mid = (l + r) >> ;
if(p <= mid) insert(ls[x], ls[y], p, v, l, mid);
else insert(rs[x], rs[y], p, v, mid + , r);
large[x] = std::max(large[ls[x]], large[rs[x]]);
//printf("[%d %d] large = %d \n", l, r, large[x]);
return;
} int ask(int L, int R, int l, int r, int o) {
if(!o) return INF;
if(L <= l && r <= R) return large[o];
int mid = (l + r) >> , ans = -INF;
if(L <= mid) ans = std::max(ans, ask(L, R, l, mid, ls[o]));
if(mid < R) ans = std::max(ans, ask(L, R, mid + , r, rs[o]));
return ans;
} int main() {
memset(large, 0x7f, sizeof(large));
scanf("%d%d%d", &lm, &q, &n);
for(int i = ; i <= n; i++) {
scanf("%d%d%d", &node[i].l, &node[i].r, &node[i].c);
X[i] = node[i].l;
}
std::sort(node + , node + n + );
std::sort(X + , X + n + );
xx = std::unique(X + , X + n + ) - X - ;
for(int i = n; i >= ; i--) {
node[i].l = std::lower_bound(X + , X + xx + , node[i].l) - X;
/// build
insert(rt[node[i].l], rt[node[i].l + ], node[i].c, node[i].r, , lm);
//printf("insert %d %d rt[%d] \n", node[i].c, node[i].r, node[i].l);
} /*printf("X : ");
for(int i = 1; i <= xx; i++) {
printf("%d ", X[i]);
}
puts("");*/ for(int i = , x, y, l, r; i <= q; i++) {
scanf("%d%d%d%d", &l, &r, &x, &y);
int t = std::lower_bound(X + , X + xx + , x) - X; //printf("i = %d t = %d \n", i, t); if(t > xx) {
printf("no\n");
//printf("ERROR 1 \n");
}
else {
t = ask(l, r, , lm, rt[t]);
if(t > y) printf("no\n");
else printf("yes\n");
//printf("t = %d \n", t);
}
fflush(stdout);
} return ;
}

AC代码

CF1080F Katya and Segments Sets的更多相关文章

  1. Codeforces Round #524 (Div. 2) F. Katya and Segments Sets(主席树)

    https://codeforces.com/contest/1080/problem/F 题意 有k个区间,区间的种类有n种,有m个询问(n,m<=1e5,k<=3e5),每次询问a,b ...

  2. Codeforces Round #523 (Div. 2) F. Katya and Segments Sets (交互题+思维)

    https://codeforces.com/contest/1061/problem/F 题意 假设存在一颗完全k叉树(n<=1e5),允许你进行最多(n*60)次询问,然后输出这棵树的根,每 ...

  3. Codeforces Round #524 (Div. 2) Solution

    A. Petya and Origami Water. #include <bits/stdc++.h> using namespace std; #define ll long long ...

  4. [UCSD白板题] Covering Segments by Points

    Problem Introduction You are given a set of segments on a line and your goal is to mark as few point ...

  5. POJ 1436 Horizontally Visible Segments (线段树&#183;区间染色)

    题意   在坐标系中有n条平行于y轴的线段  当一条线段与还有一条线段之间能够连一条平行与x轴的线不与其他线段相交  就视为它们是可见的  问有多少组三条线段两两相互可见 先把全部线段存下来  并按x ...

  6. 【37%】【poj1436】Horizontally Visible Segments

    Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 5200   Accepted: 1903 Description There ...

  7. TSQL 分组集(Grouping Sets)

    分组集(Grouping Sets)是多个分组的并集,用于在一个查询中,按照不同的分组列对集合进行聚合运算,等价于对单个分组使用“union all”,计算多个结果集的并集.使用分组集的聚合查询,返回 ...

  8. [LeetCode] Number of Segments in a String 字符串中的分段数量

    Count the number of segments in a string, where a segment is defined to be a contiguous sequence of ...

  9. grouping sets从属子句的运用

    grouping sets主要是用来合并多个分组的结果. 对于员工目标业绩表'businessTarget': employeeId targetDate idealDistAmount 如果需要分别 ...

随机推荐

  1. linux安装httpd,做文件服务器

    在一个团队或者公司层面上,做一个本地的文件服务器,将网上的资源下载到本地,是有必要的.这将节省其他人的很多下载时间. >>提君博客原创  http://www.cnblogs.com/ti ...

  2. DTW的原理及matlab实现

    参考: https://www.cnblogs.com/Daringoo/p/4095508.html

  3. Nginx安装- CentOS7

    1.确认是否具备安装环境 g++  -v 如果不打印则不具备. 解决办法:联网执行如下命令 yum install gcc yum install gcc-c++ 2.需要材料 pcre-8.37.t ...

  4. Scrapy网络爬虫框架的开发使用

    1.安装 2.使用scrapy startproject  project_name 命令创建scrapy项目 如图: 3.根据提示使用scrapy genspider spider_name dom ...

  5. linux 依赖解决办法

    在安装软件过程中如果出现依赖不满足,有两种情况: 1:你系统里面没有安装依赖软件,[但是你的软件源里面有这个软件,你只是没有安装], 这种情况很简单,通过 sudo apt-get install - ...

  6. Atcoder Beginner Contest 118 C-Monsters Battle Royale(贪心)

    题目链接 题意就是要让给出的数字去互相取余,看看能得到最小的数事多少. 那么就可以从小到大排序,每一次都贪心地把最小的数作为攻击者,去攻击其他的数字(也就是大的取余小的),然后再一次排序,循环这个过程 ...

  7. codeforces433B

    Kuriyama Mirai's Stones CodeForces - 433B 有n颗宝石,每个宝石都有自己的价值. 然后m次询问.问区间[i,j]的宝石的总值,或者问排序后的区间[i,j]的总值 ...

  8. delegate--委托

    delegate--委托 (可以把委托看成用来执行方法的一个东西) eg: namespace delegateTest{ delegate double MathsOp(double x); cla ...

  9. luogu P1353 【[USACO08JAN]跑步Running】

    USACO!!! 唉!无一例外又是母牛(终于知道美国的牧场养什么了) 今天的主人公是一个叫贝茜的公主病母牛(好洋气) 可是她叫什么和我们理解题好像没有什么关系 通过读题我们可以发现她有三个傲娇的地方 ...

  10. 微信小程序——常用快捷键【四】

    格式调整 ctrl+[, ctrl+]:代码行缩进(向前|向后) ctrl+shift+[, ctrl+shift+] :折叠打开代码块 ctrl+C, ctrl+V:复制粘贴,如果没有选中任何文件则 ...