Submission #1276823

#TimeUsernameProblemLanguageResultExecution timeMemory
1276823SmuggingSpunLong Mansion (JOI17_long_mansion)C++20
10 / 100
3094 ms15844 KiB
#include<bits/stdc++.h>
#define taskname "B"
using namespace std;
const int lim = 5e5 + 5;
template<class T>void minimize(T& a, T b){
	if(a > b){
		a = b;
	}
}
template<class T>void maximize(T& a, T b){
	if(a < b){
		a = b;
	}
}
int n, q, c[lim];
vector<int>a[lim];
namespace sub12{
	void solve(){
		vector<int>l(n + 1), r(n + 1);
		for(int i = 1; i <= n; i++){
			bitset<lim>vis;
			vis.reset();
			for(int& v : a[i]){
				vis[v] = true;
			}
			l[i] = r[i] = i;
			while((l[i] > 1 && vis[c[l[i] - 1]]) || (r[i] < n && vis[c[r[i]]])){
				while(l[i] > 1 && vis[c[l[i] - 1]]){
					l[i]--;
					for(int& v : a[l[i]]){
						vis[v] = true;
					}
				}
				while(r[i] < n && vis[c[r[i]]]){
					r[i]++;
					for(int& v : a[r[i]]){
						vis[v] = true;
					}
				}
			}
		}
		for(int _ = 0; _ < q; _++){
			int x, y;
			cin >> x >> y;			
			cout << (l[x] <= y && r[x] >= y ? "YES\n" : "NO\n");
		}
	}
}
namespace sub34{
	int parent[lim];
	int find_set(int N){
		while(N != parent[N]){
			N = parent[N] = parent[parent[N]];
		}
		return N;
	}
	void merge(int a, int b){
		parent[find_set(a)] = find_set(b);
	}
	vector<int>pos[lim];
	bitset<lim>vis;
	pair<int, int>f[lim];
	pair<int, pair<int, int>>dp(int p){
		if(vis[p]){
			return make_pair(p, make_pair(p, p));
		}
		if(f[p].first != -1){
			return make_pair(-1, f[p]);
		}
		if(find_set(p) != p){
			return dp(find_set(p));
		}
		int l = p, r = p;
		vis[p] = true;
		while(true){
			if(l > 1 && *lower_bound(pos[c[l - 1]].begin(), pos[c[l - 1]].end(), l) <= r){
				pair<int, pair<int, int>>rdp = dp(l - 1);
				minimize(l, rdp.second.first);
				maximize(r, rdp.second.second);
				if(rdp.first > 0 && rdp.first != p){
					merge(rdp.first, p);
					vis[p] = false;
					return make_pair(rdp.first, make_pair(l, r));
				}
			}
			else if(r < n && *lower_bound(pos[c[r]].begin(), pos[c[r]].end(), l) <= r){
				pair<int, pair<int, int>>rdp = dp(r + 1);
				minimize(l, rdp.second.first);
				maximize(r, rdp.second.second);
				if(rdp.first > 0 && rdp.first != p){
					merge(rdp.first, p);
					vis[p] = false;
					return make_pair(rdp.first, make_pair(l, r));
				}
			}
			else{
				break;
			}
		}
		vis[p] = false;
		return make_pair(-1, f[p] = make_pair(l, r));
	}
	void solve(){
		for(int i = 1; i <= n; i++){
			for(int& j : a[i]){
				pos[j].push_back(i);
			}
		}
		for(int i = 1; i <= n; i++){
			pos[i].push_back(lim);
			f[parent[i] = i].first = -1;
		}
		vis.reset();
		for(int i = 1; i <= n; i++){
			dp(i);
		}
		for(int i = 1; i <= n; i++){
			f[i] = f[find_set(i)];
		}
		for(int _ = 0; _ < q; _++){
			int x, y;
			cin >> x >> y;
			cout << (f[x].first <= y && f[x].second >= y ? "YES\n" : "NO\n");
		}
	}
}
int main(){
	ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
	if(fopen(taskname".inp", "r")){
		freopen(taskname".inp", "r", stdin);
	}
	cin >> n;
	for(int i = 1; i < n; i++){
		cin >> c[i];
	}
	int sum_b = 0;
	for(int i = 1; i <= n; i++){
		int k;
		cin >> k;
		for(int j = 0; j < k; j++){
			int x;
			cin >> x;
			a[i].push_back(x);
		}
		sum_b += k;
	}
	cin >> q;
	if(n <= 5000 && sum_b <= 5000){
		sub12::solve();
	}
	else{
		sub34::solve();
	}
}

Compilation message (stderr)

long_mansion.cpp: In function 'int main()':
long_mansion.cpp:130:24: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  130 |                 freopen(taskname".inp", "r", stdin);
      |                 ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...