P8819 星战 Sol
挺 nb 的一道题。
考场没想到,大失败。
会的都会,不会的怎么都不会了属于是。
首先看到每一个点只能恰好连一条边,也就是整张图内点的出度均为 。
则最后状态为 个点、 条边。
这是整张图为基环树森林的充分条件。
因为出度只能为 ,想到随机赋点权来判断整张图是否为基环树森林。
如果不为基环树森林,那么直接输出 NO。
接着,我们就保证了整张图的每一个点出度为 ,且其为基环树森林。
此时可以想一想,每一个子连通块内可以变为一个环和连在上面的一堆链。
考虑到出度必须为 ,这些链只能一致指向环的某个节点。
那么这个连通块内的每一个点都能到达一个环。
换句话说,第二个条件是第一个条件的充分条件。
即“点的出度均为 ” “可以到达环”。
没了。第一个条件是诈骗。
随机权值,维护两个数组,一个表示当前剩余的权值,一个表示当前丢失的权值。
注意 的贡献 要记到 头上。
#include <bits/stdc++.h>
using ull = unsigned long long;
using namespace std;
const int N = 5e5 + 10;
int n, m, q; mt19937_64 rnd(998244853);
ull stnd, tmp, val[N], sum[N], _sum[N];
inline void solve() {
int op, u, v; scanf("%d%d", &op, &u);
if (op == 1) scanf("%d", &v), tmp -= val[u], sum[v] -= val[u], _sum[v] += val[u];
else if (op == 2) tmp -= sum[u], _sum[u] += sum[u], sum[u] = 0;
else if (op == 3) scanf("%d", &v), tmp += val[u], sum[v] += val[u], _sum[v] -= val[u];
else tmp += _sum[u], sum[u] += _sum[u], _sum[u] = 0;
puts(tmp == stnd? "YES" : "NO"); return ;
}
int main() {
scanf("%d%d", &n, &m); for (int i = 1; i <= n; ++i) stnd += (val[i] = rnd());
for (int i = 1, u, v; i <= m; ++i) scanf("%d%d", &u, &v), sum[v] += val[u], tmp += val[u];
scanf("%d", &q); while (q--) solve();
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现