QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#511071#3405. Exclusive-ORPetroTarnavskyi#AC ✓54ms3784kbC++202.6kb2024-08-09 15:52:022024-08-09 15:52:02

Judging History

你现在查看的是最新测评结果

  • [2024-08-09 15:52:02]
  • 评测
  • 测评结果:AC
  • 用时:54ms
  • 内存:3784kb
  • [2024-08-09 15:52:02]
  • 提交

answer

#include <bits/stdc++.h>

using namespace std;

#define FOR(i, a, b) for(int i = (a); i < (b); i++)
#define RFOR(i, a, b) for(int i = (a) - 1; i >= (b); i--)
#define SZ(a) int(a.size())
#define ALL(a) a.begin(), a.end()
#define PB push_back
#define MP make_pair
#define F first
#define S second

typedef long long LL;
typedef vector<int> VI;
typedef pair<int, int> PII;
typedef double db;

int n, Q;

struct DSU
{
	int n;
	VI p, sz;
	VI xr, val;
	
	void init(int _n)
	{
		n = _n;
		p.resize(n);
		iota(ALL(p), 0);
		sz.assign(n, 1);
		xr.assign(n, 0);
		val.assign(n, -1);
	}
	PII find(int v)
	{
		if (v == p[v])
			return {v, xr[v]};
		PII res = find(p[v]);
		return {res.F, res.S ^ xr[v]};
	}
	bool unite(int u, int v, int x)
	{
		PII U = find(u);
		PII V = find(v);
		u = U.F;
		v = V.F;
		if (u == v)
			return (U.S ^ V.S) == x;
		if (sz[u] > sz[v])
			swap(u, v);
		p[u] = v;
		xr[u] = x ^ U.S ^ V.S;
		sz[v] += sz[u];
		if (val[u] != -1 && val[v] != -1 && (val[u] ^ xr[u]) != val[v])
			return false;
		if (val[u] != -1 && val[v] == -1)
			val[v] = val[u] ^ xr[u];
		return true;
	}
};

void solve()
{
	DSU d;
	d.init(n);
	int cnt = 0;
	string s;
	getline(cin, s);
	bool ok = true;
	FOR (i, 0, Q)
	{
		getline(cin, s);
		if (!ok)
			continue;
		stringstream ss(s);
		char c;
		ss >> c;
		int x;
		VI v;
		while (ss >> x)
			v.PB(x);
		if (c == 'I')
		{
			cnt++;
			if (SZ(v) == 2)
			{
				int p = v[0];
				int val = v[1];
				auto res = d.find(p);
				if (d.val[res.F] == -1)
					d.val[res.F] = val ^ res.S;
				if (d.val[res.F] != (val ^ res.S))
				{
					cout << "The first " << cnt << " facts are conflicting.\n";
					ok = false;
				}
			}
			else
			{
				assert(SZ(v) == 3);
				int p = v[0];
				int q = v[1];
				int val = v[2];
				ok &= d.unite(p, q, val);
				if (!ok)
				{
					cout << "The first " << cnt << " facts are conflicting.\n";					
				}
			}
		}
		else
		{
			assert(c == 'Q');
			int xr = 0;
			map<int, int> mp;
			FOR (j, 0, v[0])
			{
				int p = v[j + 1];
				PII res = d.find(p);
				mp[res.F]++;
				xr ^= res.S;
			}
			bool know = true;
			for (auto [p, ch] : mp)
			{
				if (ch & 1)
				{
					if (d.val[p] == -1)
						know = false;
					else
						xr ^= d.val[p];
				}
			}
			if (!know)
				cout << "I don't know.\n";
			else
				cout << xr << '\n';
			
		}
	}
}

int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	
	for (int tc = 1; ; tc++)
	{
		cin >> n >> Q;
		if (n == 0)
			break;
		cout << "Case " << tc << ":\n";
		solve();
		cout << '\n';
	}
	
	return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 54ms
memory: 3784kb

input:

5 12
I 0 1 4
I 2 3 3
I 4 5
Q 5 0 4 3 1 2
I 3 4 7
Q 1 3
Q 1 2
I 0 2 17
Q 1 0
Q 2 0 1
I 0 3 6
Q 1 2
5 14
I 0 1 4
I 2 3 3
I 4 5
Q 5 0 4 3 1 2
I 3 4 7
Q 1 3
Q 1 2
Q 3 0 1 3
I 0 2 17
I 4 5
I 0 5
Q 1 0
Q 2 0 1
Q 1 2
5 14
I 0 1 345
I 0 2 72
I 0 3 723
Q 3 1 2 3
Q 2 1 3
I 3 634
Q 3 1 2 3
Q 2 1 3
Q 1 4
Q 1 0
...

output:

Case 1:
2
2
1
16
4
The first 6 facts are conflicting.

Case 2:
2
2
1
6
The first 7 facts are conflicting.

Case 3:
I don't know.
906
875
906
I don't know.
169
496
225
634
440

Case 4:
I don't know.
I don't know.
I don't know.
I don't know.
I don't know.
1058
24209
I don't know.
I don't know.
I don't...

result:

ok 13459 lines