답안 #851335

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
851335 2023-09-19T16:15:51 Z mickey080929 Long Mansion (JOI17_long_mansion) C++17
100 / 100
2041 ms 93572 KB
#include <bits/stdc++.h>
 
using namespace std;

const int inf = 1e9;

struct SegmentTree{
public:
	int n, tree_iden;
	vector<int> tree;
	function<int(int,int)> Merge;
	SegmentTree(int _tree_iden, function<int(int,int)> _Merge) :
		tree_iden(_tree_iden), Merge(_Merge) {}
	void init(int _n) {
		n = _n;
		int sz = 1<<(Log2(n)+1);
		tree.assign(sz, tree_iden);
	}
	void update_point(int tar, int val) { update_point(1, 1, n, tar, val); }
	int query_range(int l, int r) { return query_range(1, 1, n, l, r); }
	int find_left(int l, int r) { return find_left(1, 1, n, l, r); }
	int find_right(int l, int r) { return find_right(1, 1, n, l, r); }
private:
	static int Log2(int n) {
		int ret = 0;
		while (n > 1 << ret) ret ++;
		return ret;
	}
	void Pull(int node) { tree[node] = Merge(tree[node<<1], tree[node<<1|1]); }
	void update_point(int node, int s, int e, int tar, int val) {
		if (s > tar || tar > e) return;
		if (s == e) {
			tree[node] = val;
			return;
		}
		int mid = s + e >> 1;
		update_point(node<<1, s, mid, tar, val);
		update_point(node<<1|1, mid+1, e, tar, val);
		Pull(node);
	}
	int query_range(int node, int s, int e, int l, int r) {
		if (l > e || s > r) return tree_iden;
		if (l <= s && e <= r) return tree[node];
		int mid = s + e >> 1;
		return Merge(query_range(node<<1, s, mid, l, r), query_range(node<<1|1, mid+1, e, l, r));
	}
	int find_left(int node, int s, int e, int l, int r) {
		if (l > e || s > r || tree[node] == tree_iden) return -1; 
        if (s == e) return s;
        int mid = s + e >> 1;
        int res = find_left(node<<1, s, mid, l, r);
        if (res == -1) res = find_left(node<<1|1, mid+1, e, l, r);
        return res;
    }
    int find_right(int node, int s, int e, int l, int r) {
		if (l > e || s > r || tree[node] == tree_iden) return -1; 
        if (s == e) return s;
        int mid = s + e >> 1;
        int res = find_right(node<<1|1, mid+1, e, l, r);
        if (res == -1) res = find_right(node<<1, s, mid, l, r);
        return res;
    }
};

struct LazySegmentTree{
public:
	int n, tree_iden, lazy_iden;
	vector<int> tree;
	vector<int> lazy;
	function<int(int,int)> Merge;
	LazySegmentTree(int _tree_iden, int _lazy_iden, function<int(int,int)> _Merge) : 
		tree_iden(_tree_iden), lazy_iden(_lazy_iden), Merge(_Merge) {}
	void init(int _n) {
		n = _n;
		int sz = 1<<(Log2(n)+1);
		tree.assign(sz, tree_iden);
		lazy.assign(sz, lazy_iden);
	}
	void update_point(int tar, int val) { update_point(1, 1, n, tar, val); }
	void update_range(int l, int r, int val) { update_range(1, 1, n, l, r, val); }
	int query_range(int l, int r) { return query_range(1, 1, n, l, r); }
private:
	static int Log2(int n) {
		int ret = 0;
		while (n > 1 << ret) ret ++;
		return ret;
	}
	void Pull(int node) { tree[node] = Merge(tree[node<<1], tree[node<<1|1]); }
	void Push(int node, int s, int e) {
		if (lazy[node] == lazy_iden) return;
		tree[node] = lazy[node];
		if (s != e) {
			lazy[node<<1] = lazy[node];
			lazy[node<<1|1] = lazy[node];
		}
		lazy[node] = lazy_iden;
	}
	void update_point(int node, int s, int e, int tar, int val) {
		Push(node, s, e);
		if (s > tar || tar > e) return;
		if (s == e) {
			tree[node] = val;
			return;
		}
		int mid = s + e >> 1;
		update_point(node<<1, s, mid, tar, val);
		update_point(node<<1|1, mid+1, e, tar, val);
		Pull(node);
	}
	void update_range(int node, int s, int e, int l, int r, int val) {
		Push(node, s, e);
		if (l > e || s > r) return;
		if (l <= s && e <= r) {
			lazy[node] = val;
			Push(node, s, e);
			return;
		}
		int mid = s + e >> 1;
		update_range(node<<1, s, mid, l, r, val);
		update_range(node<<1|1, mid+1, e, l, r, val);
		Pull(node);
	}
	int query_range(int node, int s, int e, int l, int r) {
		Push(node, s, e);
		if (l > e || s > r) return tree_iden;
		if (l <= s && e <= r) return tree[node];
		int mid = s + e >> 1;
		return Merge(query_range(node<<1, s, mid, l, r), query_range(node<<1|1, mid+1, e, l, r));
	}
};

SegmentTree seg(0, [] (int l, int r) { return l + r; });
LazySegmentTree Rseg(inf, inf, [] (int l, int r) { return min(l, r); });
LazySegmentTree Lseg(-inf, -inf, [] (int l, int r) { return max(l, r); });
 
int main() {
	int n, q;
	cin >> n ;
	vector<int> C(n);
	for (int i=1; i<=n-1; i++) cin >> C[i];
	vector<vector<int>> keys(n+1, vector<int>());
	for (int i=1; i<=n; i++) {
		int k; cin >> k;
		keys[i].resize(k);
		for (int j=0; j<k; j++) {
			cin >> keys[i][j];
		}
	}
	vector<int> L(n), R(n);
	vector<int> last(n+1, 0);
	for (int i=1; i<=n-1; i++) {
		for (auto &j : keys[i]) last[j] = i;
		L[i] = last[C[i]];
	}
	fill(last.begin(), last.end(), n+1);
	for (int i=n-1; i>=1; i--) {
		for (auto &j : keys[i+1]) last[j] = i+1;
		R[i] = last[C[i]];
	}
	seg.init(n);
	Rseg.init(n);
	Lseg.init(n);
	vector<vector<int>> mark(n+2, vector<int>());
	for (int i=1; i<=n-1; i++) mark[L[i]].push_back(i);
	for (auto &i : mark[0]) seg.update_point(i, 1);
	for (int i=1; i<=n-1; i++) {
		for (auto &j : mark[i]) seg.update_point(j, 1);
		if (R[i] == n+1) Lseg.update_range(i+1, n, i+1);
		else {
			int ret = seg.find_right(i+1, R[i]-1);
			if (ret != -1) Lseg.update_range(i+1, ret, i+1);
		}
	}
	seg.init(n);
	for (int i=0; i<=n+1; i++) mark[i].clear();
	for (int i=1; i<=n-1; i++) mark[R[i]].push_back(i);
	for (auto &i : mark[n+1]) seg.update_point(i, 1);
	for (int i=n-1; i>=1; i--) {
		for (auto &j : mark[i+1]) seg.update_point(j, 1);
		if (L[i] == 0) Rseg.update_range(1, i, i);
		else { 
			int ret = seg.find_left(L[i], i);
			if (ret != -1) Rseg.update_range(ret+1, i, i);
		}
	}
	cin >> q;
	while (q --) {
		int s, e;
		cin >> s >> e;
		if (Lseg.query_range(s,s) <= e && e <= Rseg.query_range(s,s)) cout << "YES\n";
		else cout << "NO\n";
	}

}

Compilation message

long_mansion.cpp: In member function 'void SegmentTree::update_point(int, int, int, int, int)':
long_mansion.cpp:36:15: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   36 |   int mid = s + e >> 1;
      |             ~~^~~
long_mansion.cpp: In member function 'int SegmentTree::query_range(int, int, int, int, int)':
long_mansion.cpp:44:15: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   44 |   int mid = s + e >> 1;
      |             ~~^~~
long_mansion.cpp: In member function 'int SegmentTree::find_left(int, int, int, int, int)':
long_mansion.cpp:50:21: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   50 |         int mid = s + e >> 1;
      |                   ~~^~~
long_mansion.cpp: In member function 'int SegmentTree::find_right(int, int, int, int, int)':
long_mansion.cpp:58:21: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   58 |         int mid = s + e >> 1;
      |                   ~~^~~
long_mansion.cpp: In member function 'void LazySegmentTree::update_point(int, int, int, int, int)':
long_mansion.cpp:105:15: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
  105 |   int mid = s + e >> 1;
      |             ~~^~~
long_mansion.cpp: In member function 'void LazySegmentTree::update_range(int, int, int, int, int, int)':
long_mansion.cpp:118:15: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
  118 |   int mid = s + e >> 1;
      |             ~~^~~
long_mansion.cpp: In member function 'int LazySegmentTree::query_range(int, int, int, int, int)':
long_mansion.cpp:127:15: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
  127 |   int mid = s + e >> 1;
      |             ~~^~~
# 결과 실행 시간 메모리 Grader output
1 Correct 13 ms 604 KB Output is correct
2 Correct 12 ms 972 KB Output is correct
3 Correct 15 ms 1444 KB Output is correct
4 Correct 11 ms 856 KB Output is correct
5 Correct 11 ms 844 KB Output is correct
6 Correct 11 ms 860 KB Output is correct
7 Correct 13 ms 1116 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 13 ms 604 KB Output is correct
2 Correct 12 ms 972 KB Output is correct
3 Correct 15 ms 1444 KB Output is correct
4 Correct 11 ms 856 KB Output is correct
5 Correct 11 ms 844 KB Output is correct
6 Correct 11 ms 860 KB Output is correct
7 Correct 13 ms 1116 KB Output is correct
8 Correct 847 ms 6560 KB Output is correct
9 Correct 854 ms 6652 KB Output is correct
10 Correct 880 ms 7208 KB Output is correct
11 Correct 909 ms 7824 KB Output is correct
12 Correct 901 ms 6016 KB Output is correct
13 Correct 867 ms 6768 KB Output is correct
14 Correct 853 ms 6712 KB Output is correct
15 Correct 858 ms 6772 KB Output is correct
16 Correct 906 ms 6524 KB Output is correct
17 Correct 837 ms 6744 KB Output is correct
18 Correct 855 ms 6876 KB Output is correct
19 Correct 837 ms 6704 KB Output is correct
20 Correct 847 ms 6640 KB Output is correct
21 Correct 894 ms 6908 KB Output is correct
22 Correct 841 ms 6744 KB Output is correct
23 Correct 850 ms 6708 KB Output is correct
24 Correct 857 ms 6584 KB Output is correct
25 Correct 845 ms 6480 KB Output is correct
26 Correct 878 ms 6464 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1110 ms 26576 KB Output is correct
2 Correct 1119 ms 26284 KB Output is correct
3 Correct 1134 ms 26172 KB Output is correct
4 Correct 1130 ms 26404 KB Output is correct
5 Correct 1149 ms 26428 KB Output is correct
6 Correct 1076 ms 26176 KB Output is correct
7 Correct 1087 ms 26132 KB Output is correct
8 Correct 1076 ms 26140 KB Output is correct
9 Correct 1086 ms 26092 KB Output is correct
10 Correct 1076 ms 26092 KB Output is correct
11 Correct 1077 ms 26048 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 13 ms 604 KB Output is correct
2 Correct 12 ms 972 KB Output is correct
3 Correct 15 ms 1444 KB Output is correct
4 Correct 11 ms 856 KB Output is correct
5 Correct 11 ms 844 KB Output is correct
6 Correct 11 ms 860 KB Output is correct
7 Correct 13 ms 1116 KB Output is correct
8 Correct 847 ms 6560 KB Output is correct
9 Correct 854 ms 6652 KB Output is correct
10 Correct 880 ms 7208 KB Output is correct
11 Correct 909 ms 7824 KB Output is correct
12 Correct 901 ms 6016 KB Output is correct
13 Correct 867 ms 6768 KB Output is correct
14 Correct 853 ms 6712 KB Output is correct
15 Correct 858 ms 6772 KB Output is correct
16 Correct 906 ms 6524 KB Output is correct
17 Correct 837 ms 6744 KB Output is correct
18 Correct 855 ms 6876 KB Output is correct
19 Correct 837 ms 6704 KB Output is correct
20 Correct 847 ms 6640 KB Output is correct
21 Correct 894 ms 6908 KB Output is correct
22 Correct 841 ms 6744 KB Output is correct
23 Correct 850 ms 6708 KB Output is correct
24 Correct 857 ms 6584 KB Output is correct
25 Correct 845 ms 6480 KB Output is correct
26 Correct 878 ms 6464 KB Output is correct
27 Correct 1110 ms 26576 KB Output is correct
28 Correct 1119 ms 26284 KB Output is correct
29 Correct 1134 ms 26172 KB Output is correct
30 Correct 1130 ms 26404 KB Output is correct
31 Correct 1149 ms 26428 KB Output is correct
32 Correct 1076 ms 26176 KB Output is correct
33 Correct 1087 ms 26132 KB Output is correct
34 Correct 1076 ms 26140 KB Output is correct
35 Correct 1086 ms 26092 KB Output is correct
36 Correct 1076 ms 26092 KB Output is correct
37 Correct 1077 ms 26048 KB Output is correct
38 Correct 1976 ms 81360 KB Output is correct
39 Correct 2041 ms 93140 KB Output is correct
40 Correct 1644 ms 68588 KB Output is correct
41 Correct 1647 ms 93572 KB Output is correct
42 Correct 1132 ms 27156 KB Output is correct
43 Correct 1088 ms 27196 KB Output is correct
44 Correct 1318 ms 47756 KB Output is correct
45 Correct 1253 ms 47808 KB Output is correct
46 Correct 1288 ms 47696 KB Output is correct
47 Correct 1086 ms 27220 KB Output is correct
48 Correct 1078 ms 27188 KB Output is correct
49 Correct 1252 ms 47528 KB Output is correct
50 Correct 1258 ms 47640 KB Output is correct
51 Correct 1238 ms 47924 KB Output is correct
52 Correct 1318 ms 47228 KB Output is correct
53 Correct 1593 ms 71780 KB Output is correct
54 Correct 1753 ms 86624 KB Output is correct
55 Correct 1522 ms 72084 KB Output is correct