답안 #369980

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
369980 2021-02-22T20:31:07 Z luciocf Joker (BOI20_joker) C++14
25 / 100
307 ms 8384 KB
#include <bits/stdc++.h>

#define ff first
#define ss second

using namespace std;

typedef pair<int, int> pii;

const int maxn = 2e5+10;

struct DSU
{
	int pai[maxn], peso[maxn], edge[maxn];
	bool bp;

	struct RollBack
	{
		int u, v, pu;
		bool b;
	};

	stack<RollBack> stk;

	void init(int n)
	{
		bp = 1;
		for (int i = 0; i < maxn; i++)
			pai[i] = i, peso[i] = 1;
	}

	int Find(int x, int &c)
	{
		if (pai[x] == x) return x;

		c ^= edge[x];

		return Find(pai[x], c);
	}

	bool Join(int x, int y)
	{
		int cx = 0, cy = 0;
		x = Find(x, cx), y = Find(y, cy);

		if (peso[x] < peso[y])
		{
			swap(x, y);
			swap(cx, cy);
		}

		stk.push({x, y, peso[x], bp});

		if (x == y) return bp = (bp && (cx != cy));

		pai[y] = x, peso[x] += peso[y];
		edge[y] = cx ^ cy ^ 1;

		return 1;
	}

	void rollback(int x)
	{
		while (stk.size() > x)
		{
			auto E = stk.top(); stk.pop();

			pai[E.u] = E.u, pai[E.v] = E.v;
			peso[E.u] = E.pu, edge[E.v] = 0;
			bp = E.b;
		}
	}
} dsu;

int n, m;

int opt[maxn];
pii edge[maxn];

void solve(int l, int r)
{
	if (l > r) return;

	int mid = (l+r)>>1, s0 = dsu.stk.size();

	for (int i = l; i <= mid; i++)
		dsu.Join(edge[i].ff, edge[i].ss);

	int s1 = dsu.stk.size();

	opt[mid] = mid;

	if (!dsu.bp) opt[mid] = opt[r+1];
	else
	{
		for (int i = opt[r+1]; i >= max(opt[l-1], mid+1); i--)
		{
			if (!dsu.Join(edge[i].ff, edge[i].ss))
			{
				opt[mid] = i;
				break;
			}
		}
	}

	dsu.rollback(s1);
	solve(mid+1, r);

	dsu.rollback(s0);
	for (int i = opt[r+1]; i > opt[mid]; i--)
		dsu.Join(edge[i].ff, edge[i].ss);

	solve(l, mid-1);

	dsu.rollback(s0);
}

int main(void)
{
	int q;
	scanf("%d %d %d", &n, &m, &q);

	for (int i = 1; i <= m; i++)
		scanf("%d %d", &edge[i].ff, &edge[i].ss);
	edge[m+1] = {0, maxn-1};

	dsu.init(n);

	opt[0] = 0, opt[m+1] = m+1;
	solve(1, m);

	while (q--)
	{
		int l, r;
		scanf("%d %d", &l, &r);

		if (opt[l] > r) printf("YES\n");
		else printf("NO\n");
	}
}

Compilation message

Joker.cpp: In member function 'void DSU::rollback(int)':
Joker.cpp:64:21: warning: comparison of integer expressions of different signedness: 'std::stack<DSU::RollBack>::size_type' {aka 'long unsigned int'} and 'int' [-Wsign-compare]
   64 |   while (stk.size() > x)
      |          ~~~~~~~~~~~^~~
Joker.cpp: In function 'int main()':
Joker.cpp:121:7: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  121 |  scanf("%d %d %d", &n, &m, &q);
      |  ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
Joker.cpp:124:8: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  124 |   scanf("%d %d", &edge[i].ff, &edge[i].ss);
      |   ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Joker.cpp:135:8: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  135 |   scanf("%d %d", &l, &r);
      |   ~~~~~^~~~~~~~~~~~~~~~~
# 결과 실행 시간 메모리 Grader output
1 Correct 2 ms 1900 KB Output is correct
2 Correct 2 ms 1900 KB Output is correct
3 Correct 2 ms 1900 KB Output is correct
4 Correct 2 ms 1900 KB Output is correct
5 Incorrect 1 ms 1900 KB Output isn't correct
6 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 2 ms 1900 KB Output is correct
2 Correct 2 ms 1900 KB Output is correct
3 Correct 2 ms 1900 KB Output is correct
4 Correct 2 ms 1900 KB Output is correct
5 Incorrect 1 ms 1900 KB Output isn't correct
6 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 2 ms 1900 KB Output is correct
2 Correct 2 ms 1900 KB Output is correct
3 Correct 183 ms 7392 KB Output is correct
4 Correct 307 ms 8384 KB Output is correct
5 Correct 167 ms 7644 KB Output is correct
6 Correct 187 ms 7264 KB Output is correct
7 Correct 185 ms 7264 KB Output is correct
8 Correct 221 ms 7260 KB Output is correct
9 Correct 238 ms 7388 KB Output is correct
10 Correct 273 ms 7732 KB Output is correct
11 Correct 215 ms 7432 KB Output is correct
12 Correct 236 ms 7580 KB Output is correct
13 Correct 217 ms 7004 KB Output is correct
14 Correct 228 ms 7132 KB Output is correct
15 Correct 263 ms 7448 KB Output is correct
16 Correct 274 ms 7644 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 2 ms 1900 KB Output is correct
2 Correct 2 ms 1900 KB Output is correct
3 Correct 2 ms 1900 KB Output is correct
4 Correct 2 ms 1900 KB Output is correct
5 Incorrect 1 ms 1900 KB Output isn't correct
6 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 2 ms 1900 KB Output is correct
2 Correct 2 ms 1900 KB Output is correct
3 Correct 2 ms 1900 KB Output is correct
4 Correct 2 ms 1900 KB Output is correct
5 Incorrect 1 ms 1900 KB Output isn't correct
6 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 2 ms 1900 KB Output is correct
2 Correct 2 ms 1900 KB Output is correct
3 Correct 2 ms 1900 KB Output is correct
4 Correct 2 ms 1900 KB Output is correct
5 Incorrect 1 ms 1900 KB Output isn't correct
6 Halted 0 ms 0 KB -