답안 #851336

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
851336 2023-09-19T16:19:06 Z mickey080929 Long Mansion (JOI17_long_mansion) C++17
100 / 100
1077 ms 88912 KB
#include <bits/stdc++.h>

#pragma GCC optimize("O3")
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
 
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() {
	ios_base :: sync_with_stdio(false); cin.tie(NULL); 
	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:40:15: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   40 |   int mid = s + e >> 1;
      |             ~~^~~
long_mansion.cpp: In member function 'int SegmentTree::query_range(int, int, int, int, int)':
long_mansion.cpp:48:15: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   48 |   int mid = s + e >> 1;
      |             ~~^~~
long_mansion.cpp: In member function 'int SegmentTree::find_left(int, int, int, int, int)':
long_mansion.cpp:54:21: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   54 |         int mid = s + e >> 1;
      |                   ~~^~~
long_mansion.cpp: In member function 'int SegmentTree::find_right(int, int, int, int, int)':
long_mansion.cpp:62:21: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   62 |         int mid = s + e >> 1;
      |                   ~~^~~
long_mansion.cpp: In member function 'void LazySegmentTree::update_point(int, int, int, int, int)':
long_mansion.cpp:109:15: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
  109 |   int mid = s + e >> 1;
      |             ~~^~~
long_mansion.cpp: In member function 'void LazySegmentTree::update_range(int, int, int, int, int, int)':
long_mansion.cpp:122:15: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
  122 |   int mid = s + e >> 1;
      |             ~~^~~
long_mansion.cpp: In member function 'int LazySegmentTree::query_range(int, int, int, int, int)':
long_mansion.cpp:131:15: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
  131 |   int mid = s + e >> 1;
      |             ~~^~~
# 결과 실행 시간 메모리 Grader output
1 Correct 4 ms 604 KB Output is correct
2 Correct 5 ms 924 KB Output is correct
3 Correct 6 ms 1372 KB Output is correct
4 Correct 3 ms 724 KB Output is correct
5 Correct 4 ms 784 KB Output is correct
6 Correct 3 ms 860 KB Output is correct
7 Correct 4 ms 860 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 4 ms 604 KB Output is correct
2 Correct 5 ms 924 KB Output is correct
3 Correct 6 ms 1372 KB Output is correct
4 Correct 3 ms 724 KB Output is correct
5 Correct 4 ms 784 KB Output is correct
6 Correct 3 ms 860 KB Output is correct
7 Correct 4 ms 860 KB Output is correct
8 Correct 173 ms 4692 KB Output is correct
9 Correct 166 ms 4596 KB Output is correct
10 Correct 184 ms 5048 KB Output is correct
11 Correct 204 ms 5884 KB Output is correct
12 Correct 164 ms 4432 KB Output is correct
13 Correct 164 ms 4904 KB Output is correct
14 Correct 165 ms 4892 KB Output is correct
15 Correct 182 ms 4688 KB Output is correct
16 Correct 201 ms 5456 KB Output is correct
17 Correct 164 ms 4884 KB Output is correct
18 Correct 164 ms 4948 KB Output is correct
19 Correct 168 ms 4948 KB Output is correct
20 Correct 178 ms 4944 KB Output is correct
21 Correct 185 ms 4956 KB Output is correct
22 Correct 173 ms 4692 KB Output is correct
23 Correct 170 ms 4472 KB Output is correct
24 Correct 175 ms 4636 KB Output is correct
25 Correct 168 ms 4436 KB Output is correct
26 Correct 164 ms 4528 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 347 ms 23124 KB Output is correct
2 Correct 337 ms 23120 KB Output is correct
3 Correct 342 ms 23372 KB Output is correct
4 Correct 337 ms 23120 KB Output is correct
5 Correct 377 ms 23048 KB Output is correct
6 Correct 317 ms 23380 KB Output is correct
7 Correct 325 ms 23356 KB Output is correct
8 Correct 330 ms 23716 KB Output is correct
9 Correct 328 ms 23272 KB Output is correct
10 Correct 331 ms 23408 KB Output is correct
11 Correct 332 ms 23380 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 4 ms 604 KB Output is correct
2 Correct 5 ms 924 KB Output is correct
3 Correct 6 ms 1372 KB Output is correct
4 Correct 3 ms 724 KB Output is correct
5 Correct 4 ms 784 KB Output is correct
6 Correct 3 ms 860 KB Output is correct
7 Correct 4 ms 860 KB Output is correct
8 Correct 173 ms 4692 KB Output is correct
9 Correct 166 ms 4596 KB Output is correct
10 Correct 184 ms 5048 KB Output is correct
11 Correct 204 ms 5884 KB Output is correct
12 Correct 164 ms 4432 KB Output is correct
13 Correct 164 ms 4904 KB Output is correct
14 Correct 165 ms 4892 KB Output is correct
15 Correct 182 ms 4688 KB Output is correct
16 Correct 201 ms 5456 KB Output is correct
17 Correct 164 ms 4884 KB Output is correct
18 Correct 164 ms 4948 KB Output is correct
19 Correct 168 ms 4948 KB Output is correct
20 Correct 178 ms 4944 KB Output is correct
21 Correct 185 ms 4956 KB Output is correct
22 Correct 173 ms 4692 KB Output is correct
23 Correct 170 ms 4472 KB Output is correct
24 Correct 175 ms 4636 KB Output is correct
25 Correct 168 ms 4436 KB Output is correct
26 Correct 164 ms 4528 KB Output is correct
27 Correct 347 ms 23124 KB Output is correct
28 Correct 337 ms 23120 KB Output is correct
29 Correct 342 ms 23372 KB Output is correct
30 Correct 337 ms 23120 KB Output is correct
31 Correct 377 ms 23048 KB Output is correct
32 Correct 317 ms 23380 KB Output is correct
33 Correct 325 ms 23356 KB Output is correct
34 Correct 330 ms 23716 KB Output is correct
35 Correct 328 ms 23272 KB Output is correct
36 Correct 331 ms 23408 KB Output is correct
37 Correct 332 ms 23380 KB Output is correct
38 Correct 1039 ms 75768 KB Output is correct
39 Correct 1077 ms 87776 KB Output is correct
40 Correct 786 ms 63456 KB Output is correct
41 Correct 783 ms 88912 KB Output is correct
42 Correct 320 ms 23856 KB Output is correct
43 Correct 333 ms 23912 KB Output is correct
44 Correct 427 ms 42712 KB Output is correct
45 Correct 436 ms 42836 KB Output is correct
46 Correct 427 ms 42740 KB Output is correct
47 Correct 323 ms 23740 KB Output is correct
48 Correct 321 ms 23736 KB Output is correct
49 Correct 403 ms 42868 KB Output is correct
50 Correct 422 ms 42932 KB Output is correct
51 Correct 439 ms 42788 KB Output is correct
52 Correct 522 ms 42840 KB Output is correct
53 Correct 606 ms 61048 KB Output is correct
54 Correct 751 ms 73996 KB Output is correct
55 Correct 635 ms 60608 KB Output is correct