답안 #353953

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
353953 2021-01-21T11:05:25 Z arnold518 Mostovi (COI14_mostovi) C++14
100 / 100
709 ms 45696 KB
#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

const int MAXN = 1e9;
const int MAXM = 4e5;

int N, M;
int N1, N2;
struct Query
{
	char c; int x, y;
};
Query A[MAXM+10];

vector<int> comp1, comp2;
int par[MAXM+10];

int L[MAXM+10], R[MAXM+10];
set<pii> S[MAXM+10];
set<pii> S1, S2;

void init()
{
	for(int i=1; i<=MAXM; i++)
	{
		par[i]=i;
		L[i]=R[i]=i;
		S[i].clear();
	}
}

int Find(int x)
{
	if(x==par[x]) return x;
	return par[x]=Find(par[x]);
}

void Union(int x, int y)
{
	x=Find(x); y=Find(y);
	assert(x!=y);
	if(S[x].size()>S[y].size()) swap(x, y);
	for(auto it : S[x]) S[y].insert(it);
	S[x].clear();
	par[x]=y;
	L[y]=min(L[y], L[x]);
	R[y]=max(R[x], R[y]);
}

bool solve(int s, int e)
{
	//printf("SOLVE %d %d\n", s, e);
	if(s<=N1 && e>N1)
	{
		int u=Find(s), v=Find(e);
		if(S[u].empty()) return false;
		auto it=S[u].lower_bound(pii(L[v], 0));
		auto jt=S[u].lower_bound(pii(R[v], 2e9));
		if(it==jt) return false;
		jt--;
		int l1, r1, l2, r2;
		l1=it->second; r1=jt->second;
		l2=it->first; r2=jt->first;
		if(r1<s) return false;
		if(r2<e) return false;
		return true;
	}
	if(s>N1 && e<=N1)
	{
		int u=Find(s), v=Find(e);
		if(S[u].empty()) return false;
		auto it=S[u].lower_bound(pii(L[v], 0));
		auto jt=S[u].lower_bound(pii(R[v], 2e9));
		if(it==jt) return false;
		jt--;
		int l1, r1, l2, r2;
		l1=it->second; r1=jt->second;
		l2=it->first; r2=jt->first;
		if(s<l1) return false;
		if(e<l2) return false;
		return true;	
	}
	if(s<=N1 && e<=N1)
	{
		int u=Find(s), v=Find(e);
		if(u<v) return false;
		if(u>v)
		{
			if(S[u].empty()) return false;
			int it=S[u].begin()->first;
			return solve(s, it) && solve(it, e);
		}
		if(u==v)
		{
			if(s<e) return true;
			auto it=S2.lower_bound(pii({s, 0}));
			auto jt=S2.lower_bound(pii({e, 2e9}));
			if(it==S2.end()) return false;
			if(jt==S2.begin()) return false;
			jt--;
			if(Find(it->first)!=u) return false;
			if(Find(jt->first)!=u) return false;
			if(Find(it->second)==Find(jt->second)) return true;
			else return false;
		}
	}
	if(s>N1 && e>N1)
	{
		//printf("HI\n");
		int u=Find(s), v=Find(e);
		if(u>v) return false;
		if(u<v)
		{
			if(S[u].empty()) return false;
			int it=(--S[u].end())->first;
			//printf("%d\n", it);
			return solve(s, it) && solve(it, e);
		}
		if(u==v)
		{
			if(s>e) return true;
			auto it=S1.lower_bound(pii({e, 0}));
			auto jt=S1.lower_bound(pii({s, 2e9}));
			if(it==S1.end()) return false;
			if(jt==S1.begin()) return false;
			jt--;
			if(Find(it->first)!=u) return false;
			if(Find(jt->first)!=u) return false;
			if(Find(it->second)==Find(jt->second)) return true;
			else return false;
		}
	}
}

int chk[MAXM+10];

int main()
{
	scanf("%d%d", &N, &M);
	for(int i=1; i<=M; i++)
	{
		scanf(" %c%d%d", &A[i].c, &A[i].x, &A[i].y);
		if(A[i].x<=N) comp1.push_back(A[i].x);
		else comp2.push_back(A[i].x);
		if(A[i].y<=N) comp1.push_back(A[i].y);
		else comp2.push_back(A[i].y);
		if(A[i].c!='Q' && A[i].x>A[i].y) swap(A[i].x, A[i].y);
	}

	sort(comp1.begin(), comp1.end());
	comp1.erase(unique(comp1.begin(), comp1.end()), comp1.end());

	sort(comp2.begin(), comp2.end());
	comp2.erase(unique(comp2.begin(), comp2.end()), comp2.end());

	N1=comp1.size();
	N2=comp2.size();

	for(int i=1; i<=M; i++)
	{
		if(A[i].x<=N) A[i].x=lower_bound(comp1.begin(), comp1.end(), A[i].x)-comp1.begin()+1;
		else A[i].x=lower_bound(comp2.begin(), comp2.end(), A[i].x)-comp2.begin()+1+N1;

		if(A[i].y<=N) A[i].y=lower_bound(comp1.begin(), comp1.end(), A[i].y)-comp1.begin()+1;
		else A[i].y=lower_bound(comp2.begin(), comp2.end(), A[i].y)-comp2.begin()+1+N1;
	}

	init();
	for(int i=1; i<=M; i++)
	{
		if(A[i].c=='B')
		{
			chk[A[i].x]++;
		}
		if(A[i].c=='A')
		{
			S[A[i].x].insert({A[i].y, A[i].x});
			S[A[i].y].insert({A[i].x, A[i].y});

			S1.insert({A[i].y, A[i].x});
			S2.insert({A[i].x, A[i].y});
		}
	}

	for(int i=1; i<=N1+N2; i++)
	{
		if(i==N1) continue;
		if(i==N1+N2) continue;
		if(chk[i]) continue;
		Union(i, i+1);
	}

	vector<int> ans;
	for(int i=M; i>=1; i--)
	{
		//printf("DONE %d\n", i);
		if(A[i].c=='A')
		{
			assert(A[i].x<=N1);
			assert(A[i].y>N1);
			S[Find(A[i].x)].erase({A[i].y, A[i].x});
			S[Find(A[i].y)].erase({A[i].x, A[i].y});

			S1.erase({A[i].y, A[i].x});
			S2.erase({A[i].x, A[i].y});
		}
		if(A[i].c=='B')
		{
			assert(A[i].x+1==A[i].y);
			Union(A[i].x, A[i].y);
		}
		if(A[i].c=='Q')
		{
			if(solve(A[i].x, A[i].y)) ans.push_back(1);
			else ans.push_back(0);
		}
	}

	reverse(ans.begin(), ans.end());
	for(auto it : ans)
	{
		if(it) printf("DA\n");
		else printf("NE\n");
	}
}

Compilation message

mostovi.cpp: In function 'bool solve(int, int)':
mostovi.cpp:65:7: warning: variable 'l1' set but not used [-Wunused-but-set-variable]
   65 |   int l1, r1, l2, r2;
      |       ^~
mostovi.cpp:65:15: warning: variable 'l2' set but not used [-Wunused-but-set-variable]
   65 |   int l1, r1, l2, r2;
      |               ^~
mostovi.cpp:80:11: warning: variable 'r1' set but not used [-Wunused-but-set-variable]
   80 |   int l1, r1, l2, r2;
      |           ^~
mostovi.cpp:80:19: warning: variable 'r2' set but not used [-Wunused-but-set-variable]
   80 |   int l1, r1, l2, r2;
      |                   ^~
mostovi.cpp:137:1: warning: control reaches end of non-void function [-Wreturn-type]
  137 | }
      | ^
mostovi.cpp: In function 'int main()':
mostovi.cpp:143:7: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  143 |  scanf("%d%d", &N, &M);
      |  ~~~~~^~~~~~~~~~~~~~~~
mostovi.cpp:146:8: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  146 |   scanf(" %c%d%d", &A[i].c, &A[i].x, &A[i].y);
      |   ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# 결과 실행 시간 메모리 Grader output
1 Correct 18 ms 23788 KB Output is correct
2 Correct 20 ms 23788 KB Output is correct
3 Correct 19 ms 23916 KB Output is correct
4 Correct 19 ms 23916 KB Output is correct
5 Correct 19 ms 23916 KB Output is correct
6 Correct 19 ms 23788 KB Output is correct
7 Correct 380 ms 39312 KB Output is correct
8 Correct 602 ms 40664 KB Output is correct
9 Correct 317 ms 36184 KB Output is correct
10 Correct 709 ms 45696 KB Output is correct