Submission #125438

#TimeUsernameProblemLanguageResultExecution timeMemory
125438onjo0127Long Mansion (JOI17_long_mansion)C++11
100 / 100
786 ms112092 KiB
#include <bits/stdc++.h>
using namespace std;
using pii = pair<int, int>;
using tiii = tuple<int, int, int>;

struct minseg {
	vector<int> T;
	void init(vector<int> &A, int idx, int s, int e) {
		if(s == e) {
			T[idx] = A[s];
			return;
		}
		int m = s+e >> 1;
		init(A, idx*2, s, m);
		init(A, idx*2+1, m+1, e);
		T[idx] = min(T[idx*2], T[idx*2+1]);
	}
	// 구간 [l, r]에서 v 이하이면서 가장 오른쪽에 있는 원소 위치 리턴
	int find(int idx, int s, int e, int l, int r, int v) {
		if(r < s || e < l || T[idx] > v) return -1;
		if(s == e) return s;
		int m = s+e >> 1;
		int tmp = find(idx*2+1, m+1, e, l, r, v);
		if(tmp != -1) return tmp;
		return find(idx*2, s, m, l, r, v);
	}
	minseg(int sz) {
		T.resize(sz*4);
	}
};

struct maxseg {
	vector<int> T;
	void init(vector<int> &A, int idx, int s, int e) {
		if(s == e) {
			T[idx] = A[s];
			return;
		}
		int m = s+e >> 1;
		init(A, idx*2, s, m);
		init(A, idx*2+1, m+1, e);
		T[idx] = max(T[idx*2], T[idx*2+1]);
	}
	// 구간 [l, r]에서 v 이상이면서 가장 왼쪽에 있는 원소 위치 리턴
	int find(int idx, int s, int e, int l, int r, int v) {
		if(r < s || e < l || T[idx] < v) return -1;
		if(s == e) return s;
		int m = s+e >> 1;
		int tmp = find(idx*2, s, m, l, r, v);
		if(tmp != -1) return tmp;
		return find(idx*2+1, m+1, e, l, r, v);
	}
	maxseg(int sz) {
		T.resize(sz*4);
	}
};

int LM[500009], RM[500009];
int C[500009], B[500009], L[500009], R[500009], LE[500009], RE[500009];
vector<int> A[500009], P[500009];

int main() {
	int N; scanf("%d",&N);
	for(int i=1; i<N; i++) scanf("%d", &C[i]);
	for(int i=1; i<=N; i++) P[i].push_back(0);
	for(int i=1; i<=N; i++) {
		scanf("%d",&B[i]);
		for(int j=0; j<B[i]; j++) {
			int foo; scanf("%d",&foo);
			P[foo].push_back(i);
			A[i].push_back(foo);
		}
	}
	for(int i=1; i<=N; i++) P[i].push_back(N+1);
	R[0] = N+1; L[N] = 0;
	for(int i=1; i<N; i++) {
		L[i] = *(--upper_bound(P[C[i]].begin(), P[C[i]].end(), i));
		R[i] = *upper_bound(P[C[i]].begin(), P[C[i]].end(), i);
	}
	minseg LG(N+1); maxseg RG(N+1);
	vector<int> LS = {-1}, RS;
	for(int i=1; i<=N; i++) LS.push_back(L[i]);
	for(int i=0; i<N; i++) RS.push_back(R[i]);
	LG.init(LS, 1, 1, N); RG.init(RS, 1, 0, N-1);

	for(int i=0; i<N; i++) {
		int s = i+1, e = LG.find(1, 1, N, i+1, R[i]-1, i);
		// printf("LEFT INTERVAL: [%d, %d]\n", s, e);
		LE[s] = e;
	}
	for(int i=1; i<=N; i++) {
		int s = RG.find(1, 0, N-1, L[i], i-1, i+1) + 1, e = i;
		// printf("RIGHT INTERVAL: [%d, %d]\n", s, e);
		RE[e] = s;
	}

	for(int i=1; i<=N; i++) LM[i] = 0, RM[i] = N+1;

	priority_queue<pii> LPQ, RPQ;
	for(int i=1; i<=N; i++) {
		while(LPQ.size() && LPQ.top().second < i) LPQ.pop();
		if(LE[i] > 0) LPQ.push({i, LE[i]});
		if(LPQ.size()) LM[i] = LPQ.top().first;
	}
	for(int i=N; i>=1; i--) {
		while(RPQ.size() && i < RPQ.top().second) RPQ.pop();
		if(RE[i] > 0) RPQ.push({-i, RE[i]});
		if(RPQ.size()) RM[i] = -RPQ.top().first;
	}

	for(int i=1; i<=N; i++) {
		// printf("i: %d, LM: %d, RM: %d\n", i, LM[i], RM[i]);
	}

	int Q; scanf("%d",&Q);
	while(Q--) {
		int X, Y; scanf("%d%d",&X,&Y);
		if(LM[X] <= Y && Y <= RM[X]) puts("YES");
		else puts("NO");
	}
	return 0;
}

Compilation message (stderr)

long_mansion.cpp: In member function 'void minseg::init(std::vector<int>&, int, int, int)':
long_mansion.cpp:13:12: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   int m = s+e >> 1;
           ~^~
long_mansion.cpp: In member function 'int minseg::find(int, int, int, int, int, int)':
long_mansion.cpp:22:12: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   int m = s+e >> 1;
           ~^~
long_mansion.cpp: In member function 'void maxseg::init(std::vector<int>&, int, int, int)':
long_mansion.cpp:39:12: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   int m = s+e >> 1;
           ~^~
long_mansion.cpp: In member function 'int maxseg::find(int, int, int, int, int, int)':
long_mansion.cpp:48:12: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   int m = s+e >> 1;
           ~^~
long_mansion.cpp: In function 'int main()':
long_mansion.cpp:63:14: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  int N; scanf("%d",&N);
         ~~~~~^~~~~~~~~
long_mansion.cpp:64:30: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  for(int i=1; i<N; i++) scanf("%d", &C[i]);
                         ~~~~~^~~~~~~~~~~~~
long_mansion.cpp:67:8: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
   scanf("%d",&B[i]);
   ~~~~~^~~~~~~~~~~~
long_mansion.cpp:69:18: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
    int foo; scanf("%d",&foo);
             ~~~~~^~~~~~~~~~~
long_mansion.cpp:115:14: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  int Q; scanf("%d",&Q);
         ~~~~~^~~~~~~~~
long_mansion.cpp:117:18: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
   int X, Y; scanf("%d%d",&X,&Y);
             ~~~~~^~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...