P9869 [NOIP2023] 三值逻辑
赛时做法。
钦定
发现每个值都有两个状态,它本身及其取反。
在
-
没有对这个值进行操作,不知晓任何信息。
-
这个值与另外一个值有关,能从另外一个值推出当前值。
-
已经确定是
。
考虑定义数组
对于第二种情况,定义数组
此时很容易处理出输入部分的代码。
while (m --) {
char op;
int x, y;
cin >> op;
if (op == '+') {
cin >> x >> y;
if (ok[y]) {
ok[x] = true;
val[x] = val[y];
} else {
ok[x] = false;
p[x] = p[y];
sig[x] = sig[y];
}
} else if (op == '-') {
cin >> x >> y;
if (ok[y]) {
ok[x] = true;
val[x] = -val[y];
} else {
ok[x] = false;
p[x] = p[y];
sig[x] = -sig[y];
}
} else {
cin >> x;
ok[x] = true;
if (op == 'U') {
val[x] = 0;
} else if (op == 'T') {
val[x] = 1;
} else {
val[x] = -1;
}
}
}
考虑如何对答案进行计数。
首先显然的是如果一个值已经确定为
其次如果经过操作后,我们得到了
对于一个
不难得到别的情况都有一种方案使得不是
如何处理和某个值相等 / 相反的值?
这是扩展域并查集的经典问题。
让
如果一个
如果一个
注意计算答案时一个集合的答案只能算一次,但一个集合中可能有多个数都满足,所以算完一个集合的答案后要把这个集合的
让一个数
代码思路比较清晰,应该有比我更简洁的写法。
int find(int x) {
return fa[x] == x ? x : fa[x] = find(fa[x]);
}
void merge(int x, int y) {
x = find(x), y = find(y);
if (x == y) return;
fa[x] = y, siz[y] += siz[x];
}
void add(int &res, int x) {
x = find(x);
res += siz[x];
siz[x] = 0;
}
void solve() {
cin >> n >> m;
for (int i = 1; i <= n; i ++) {
ok[i] = false, val[i] = 0;
p[i] = i, sig[i] = 1;
}
for (int i = 1; i <= n * 2; i ++) {
fa[i] = i, siz[i] = i <= n;
}
while (m --) {
char op;
int x, y;
cin >> op;
if (op == '+') {
cin >> x >> y;
if (ok[y]) {
ok[x] = true;
val[x] = val[y];
} else {
ok[x] = false;
p[x] = p[y];
sig[x] = sig[y];
}
} else if (op == '-') {
cin >> x >> y;
if (ok[y]) {
ok[x] = true;
val[x] = -val[y];
} else {
ok[x] = false;
p[x] = p[y];
sig[x] = -sig[y];
}
} else {
cin >> x;
ok[x] = true;
if (op == 'U') {
val[x] = 0;
} else if (op == 'T') {
val[x] = 1;
} else {
val[x] = -1;
}
}
}
for (int i = 1; i <= n; i ++) {
if (ok[i]) continue;
int x = p[i];
if (sig[x] == 1) {
merge(i, x), merge(i + n, x + n);
} else {
merge(i + n, x), merge(x + n, i);
}
}
int res = 0;
for (int i = 1; i <= n; i ++) {
if (ok[i] && val[i] == 0) {
add(res, i), add(res, i + n);
} else if (find(i) == find(i + n)) {
add(res, i);
}
}
cout << res << "\n";
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!