填数游戏

题目大意:小 Y 得到了一个长度为 𝑛 的画板和 𝑚 支画笔。经过尝试,他发现编号为 𝑖的画笔能够对画板的第 𝑙𝑖 格到第 𝑟𝑖 格染色。现在小 Y 有 𝑞 次询问,每次他想知道编号在 [𝑥, 𝑦] 内的画笔能否将画板上的区间 [𝑠,𝑡] 中的每一格都染色。

其实拿暴力分的话,做法很多,UFS,莫队套分块,莫队套线段树

正解的思想很巧妙,利用时间戳,可以很巧妙的计算完成这个区间最早需要的时间戳与他规定的开始时间

为什么只比较开始时间?想一想,为什么

因为他插进去vector的时候,就是在右端点插进去的,这样就保证了,他比较的时候,右端点一定相同

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#include <bits/stdc++.h>
using namespace std;

const int N = 1e6 + 66;

struct yhm
{
int x, l, r, id;
//constructor
yhm(int X = 0, int L = 0, int R = 0, int ID = 0):x(X), l(L), r(R), id(ID){}
};

struct SEGMENTTREE
{
int tag, minv;
}tree[N << 2];

vector<yhm>vec[N];
int n, m, q;
int l[N], r[N], ans[N];

inline void up(int p)
{
int l = p << 1, r = (p << 1) | 1;
return (void)(tree[p].minv = min(tree[l].minv, tree[r].minv));
}

inline void down(int p)
{
int l = p << 1, r = (p << 1) | 1, c = tree[p].tag;
if (! c) return;
tree[l].tag = tree[l].minv = c;
tree[r].tag = tree[r].minv = c;
return (void)(tree[p].tag = 0);
}

inline void updata(int p, int l, int r, int nl, int nr, int c)
{
if (nl <= l && nr >= r) return (void)(tree[p].minv = tree[p].tag = c);
down(p);
int mid = (l + r) >> 1;
if (nl <= mid) updata(p << 1, l, mid, nl, nr, c);
if (nr > mid) updata((p << 1) | 1, mid + 1, r, nl, nr, c);
return (void)(up(p));
}

inline int query(int p, int l, int r, int nl, int nr)
{
if (nl <= l && nr >= r) return tree[p].minv;
down(p);
int mid = (l + r) >> 1, res = 0x7fffffff;
if (nl <= mid) res = min(res, query(p << 1, l, mid, nl, nr));
if (nr > mid) res = min(res, query((p << 1) | 1, mid + 1, r, nl, nr));
return res;
}

signed main()
{

int i, j;
n = read(), m = read(), q = read();
for (i = 1; i <= m; ++ i) l[i] = read(), r[i] = read();
for (i = 1; i <= q; ++ i)
{
int x, y, s, t;
x = read(), y = read(), s = read(), t = read();
vec[y].push_back(yhm(x, s, t, i));
}

for (i = 1; i <= m; ++ i)
{
updata(1, 1, n, l[i], r[i], i);
for (j = 0; j < (int)vec[i].size(); ++ j)
{
ans[vec[i][j].id] = query(1, 1, n, vec[i][j].l, vec[i][j].r) >= vec[i][j].x;
}
}

for (i = 1; i <= q; ++ i) put(ans[i]);
return 0;
}