思路
- 尽管这道题想让我们在线做, 但是我还是想离线哈哈
- 题目中既有撤销(回到第 k 个版本), 又涉及并查集, 想到用可撤销并查集
- 如果我们按照一般思路撤销来做, 就不得不将每个历史版本存一遍(很明显不可能)
- 如果第 i 次操作让我们回到第 k 次操作, 那我们何不在第 k 次操作进行完之后接着就进行第 i 次操作呢
- 给操作序列建图
- 对于 opt 1, 3, 由 i - 1 向 i 连边
- 对于 opt 2, 由 k 向 i 连边
- 然后从 0 节点开始 Dfs
- Dfs 之前记录下当前状态(并查集合并了几步), 遍历完所有子树之后将并查集恢复到初始状态, 然后返回
代码
| # include <bits/stdc++.h> |
| # define int long long |
| using namespace std; |
| const int N = 2e5 + 10; |
| |
| int n, m; |
| int opt[N], a[N], b[N], k[N], ans[N]; |
| int si[N]; |
| vector <int> e[N]; |
| |
| struct Ufs{ |
| int s[N], si[N], cnt; |
| int st[N], tp; |
| |
| inline void Insert(){ |
| ++cnt; |
| s[cnt] = cnt; |
| si[cnt] = 1; |
| } |
| |
| int Find(int x){ |
| if(x != s[x]){ |
| return Find(s[x]); |
| } |
| return s[x]; |
| } |
| |
| void Merge(int x, int y){ |
| int fa = Find(x); |
| int fb = Find(y); |
| if(fa == fb){ |
| return; |
| } |
| if(si[fa] < si[fb]){ |
| swap(fa, fb); |
| } |
| s[fb] = fa; |
| si[fa] += si[fb]; |
| st[++tp] = fb; |
| } |
| |
| void Delete(int x){ |
| while(tp > x){ |
| int k = st[tp]; |
| si[s[k]] -= si[k]; |
| s[k] = k; |
| tp--; |
| } |
| } |
| }s; |
| |
| void Dfs(int x){ |
| si[x] = s.tp; |
| if(opt[x] == 1ll){ |
| s.Merge(a[x], b[x]); |
| }else if(opt[x] == 3ll){ |
| ans[x] = (s.Find(a[x]) == s.Find(b[x])); |
| } |
| for(auto i : e[x]){ |
| Dfs(i); |
| } |
| s.Delete(si[x]); |
| } |
| |
| signed main(){ |
| |
| ios::sync_with_stdio(0); |
| cin.tie(0); cout.tie(0); |
| |
| cin >> n >> m; |
| for(int i = 1; i <= n; i++){ |
| s.Insert(); |
| } |
| for(int i = 1; i <= m; i++){ |
| cin >> opt[i]; |
| if(opt[i] == 1){ |
| cin >> a[i] >> b[i]; |
| e[i - 1].push_back(i); |
| }else if(opt[i] == 2){ |
| cin >> k[i]; |
| e[k[i]].push_back(i); |
| }else{ |
| cin >> a[i] >> b[i]; |
| e[i - 1].push_back(i); |
| } |
| } |
| Dfs(0); |
| for(int i = 1; i <= m; i++){ |
| if(opt[i] == 3){ |
| cout << ans[i] << "\n"; |
| } |
| } |
| } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话