当前位置: 首页 > news >正文

P14480 化作彗星 题解

Description

为了再现那日的彗星,Nana 和 Lily 需要使用特定的数对把一个序列变成另一个序列。

Nana 有一个长度为 \(n\) 序列 \(a\),Lily 每次可以选择一个下标 \(i(1\le i<n)\),然后操作 \(a_i\leftarrow x,a_{i+1}\leftarrow y\)

选定的 \(1\le x,y\le k\) 需要满足 \(f(a_i,a_{i+1})=f(x,y)=1\)。Lily 最后需要把 \(a\) 变成另一个长度为 \(n\) 的序列 \(b\)

其中,Nana 将给出一个 \(k\) 个点 \(m\) 条边的无向图 \(G\)保证没有重边和自环,则 \(f(x,y)=1\) 当且仅当图上 \(x\)\(y\) 之间存在连边。需要注意的是,如果有 \(x\)\(x\) 之间的连边(一个自环)则 \(f(x,x)=1\),否则 \(f(x,x)=0\)

Lily 并不太关心构造的方案,所以她想让你多组测试询问 \(a\) 是否能变成另一个长度为 \(n\) 的序列 \(b\)

\(1\le T\le 10^4,2\le n\le 10^5,\sum n\le 10^6,1\le m\le 3\times 10^5,1\le k\le 2\times 10^5\)

保证图没有重边和自环。

Solution

首先如果存在一个 \(a_i\) 是孤立点,则 \(a_i\) 一定不会移动,所以可以把这些孤立点判掉。同时如果序列中目前不存在任何边,则完全不能操作,也判掉。

现在假设所有 \(a_i\)\(b_i\) 都不是孤立点且存在至少一条边。

现有的操作还是太弱,考虑找一些好用的组合操作。如果现在存在一个子段 \([x,u,v]\),其中 \((u,v)\) 是一条边。由于 \(x\) 不是孤立点,所以一定存在两条边是 \((x,y)\)\((y,z)\),那么我们可以做一些操作:\([x,u,v]\to[x,y,x]\to[u,v,x]\),以及 \([x,u,v]\to[x,y,x]\to[z,y,x]\to[z,u,v]\)

这两个操作的含义就是可以让一条已经存在的边随意移动,以及可以让这条边旁边的点在图上任意走偶数步。

所以如果初始存在至少一条边,我们就可以让序列中的所有点在图上任意走偶数步。根据这个结论可以推出如果相邻的 \(a_i\)\(a_{i+1}\) 可以通过走奇数步互相到达,则可以看成新加了一条 \((a_i,a_{i+1})\) 的边。

然后考虑怎么判定两个序列能够互相操作得到。注意到操作可逆,所以策略是每次找到一对相邻的 \(a_i\)\(a_{i+1}\),如果它们可以走奇数步互相到达,就把 \(a_i\)\(a_{i+1}\) 删掉。


让两个序列都按照上面的策略做最多的操作次数,假设最后剩下的点为 \(c_1,c_2,\ldots,c_{t_1}\)\(d_1,d_2,\ldots,d_{t_2}\),判断 \(t_1=t_2\) 以及 \(c_i\)\(d_i\) 都能通过走偶数步互相到达。

操作出剩余的点数显然要相同,但是最后剩下的 \(c\) 数组不一定固定,就不好判断了。

注意到走偶数步能互相到达的点是互相等价的,所以每个点可以看成一个带颜色的括号,每次选择颜色相同的括号进行匹配。这是个比较典的问题,维护一个栈,新加入一个括号的时候判断和栈顶能不能匹配,能匹配的就弹栈,否则把新加入的括号加入栈中。

最终剩下的栈一定是唯一的,所以判断两个序列做匹配剩余的栈是否等价即可。

时间复杂度:\(O((n+m)\log k+k)\)

Solution

#include <bits/stdc++.h>// #define int int64_tconst int kMaxN = 3e5 + 5;int n, m, k;
int a[kMaxN], b[kMaxN];
bool vis[kMaxN];
std::unordered_map<int, bool> mp[kMaxN];struct DSU {int fa[kMaxN * 2];void init(int n) { std::iota(fa + 1, fa + 1 + n, 1); }int find(int x) { return x == fa[x] ? x : fa[x] = find(fa[x]); }void unionn(int x, int y) {int fx = find(x), fy = find(y);if (fx != fy) fa[fx] = fy;}
} dsu;void prework() {dsu.init(2 * k);for (int i = 1; i <= m; ++i) {int u, v;std::cin >> u >> v;mp[u][v] = mp[v][u] = 1;dsu.unionn(u, v + k), dsu.unionn(v, u + k);vis[u] = vis[v] = 1;}
}std::vector<int> getstk(int n, int *a) {std::vector<int> stk;for (int i = 1; i <= n; ++i) {if (stk.size() && dsu.find(stk.back() + k) == dsu.find(a[i])) stk.pop_back();else stk.emplace_back(a[i]);}return stk;
}void dickdreamer() {std::cin >> n;for (int i = 1; i <= n; ++i) std::cin >> a[i];for (int i = 1; i <= n; ++i) std::cin >> b[i];for (int i = 1; i <= n; ++i)if (vis[a[i]] != vis[b[i]] || !vis[a[i]] && a[i] != b[i])return void(std::cout << "NO\n");for (int i = 1, lst = 0; i <= n + 1; ++i) {if (i == n + 1 || !vis[a[i]]) {bool fla = 0, flb = 0;for (int j = lst + 1; j < i - 1; ++j) {if (mp[a[j]].count(a[j + 1])) fla = 1;if (mp[b[j]].count(b[j + 1])) flb = 1;}if (!fla || !flb) {for (int j = lst + 1; j <= i - 1; ++j)if (a[j] != b[j])return void(std::cout << "NO\n");} else {auto stka = getstk(i - lst - 1, a + lst), stkb = getstk(i - lst - 1, b + lst);if (stka.size() != stkb.size()) return void(std::cout << "NO\n");for (int j = 0; j < stka.size(); ++j)if (dsu.find(stka[j]) != dsu.find(stkb[j]))return void(std::cout << "NO\n");}lst = i;}}std::cout << "YES\n";
}int32_t main() {
#ifdef ORZXKRfreopen("in.txt", "r", stdin);freopen("out.txt", "w", stdout);
#endifstd::ios::sync_with_stdio(0), std::cin.tie(0), std::cout.tie(0);int T = 1;std::cin >> m >> k >> T;prework();while (T--) dickdreamer();// std::cerr << 1.0 * clock() / CLOCKS_PER_SEC << "s\n";return 0;
}
http://www.rkmt.cn/news/47703.html

相关文章:

  • PG系列:Select查询一样会被阻塞
  • 制作自己的最小操作系统
  • .NET 10性能突破:持续优化才是质变关键
  • 植物大战僵尸经典版下载教程:重新体验最纯粹的塔防乐趣
  • 5 CSRF 攻击防范
  • 11.12记录-机器学习
  • 个人工作版(Linux)
  • 2025年耙式真空干燥机优质厂家权威推荐榜单:耙式干燥机/ZB系列耙式真空干燥机/真空耙式干燥机源头厂家精选
  • 习题解析之:输出 n 以内的所有素数
  • 2025年重庆吊装搬运公司权威推荐榜单:工厂搬迁/搬运/搬运设备源头公司精选
  • 新手入门常用的Dos命令
  • 到底是用vue2还是vue3好?
  • 避免在C#循环中使用await 改用WhenAll - 尼古拉
  • P12213 [蓝桥杯 2023 国 Python B] 最长回文前后缀 题解 字符串哈希+二分
  • 智能充气泵方案:充气泵pcba功能结构组成
  • 习题解析之:最大素数
  • mybatis-plus Wrappers相关Api
  • 塔城西林瓶灌装线厂家提供使用技巧培训助提效
  • VMware-配置静态IP地址详细教程
  • OI教练模拟器自动刷天赋脚本!
  • BM3D 图像降噪快速算法的 MATLAB 实现
  • v4l2 probe时各个device的操作顺序
  • 国泰君安基于隐语SecretFlow生产场景探索实践
  • 鲜花:m 群 bot 随机一言摘抄
  • MATLAB小波分析工具包进行时间序列的小波功率谱分析
  • 再次出山!!
  • 完整教程:Java 反射机制核心类详解:Class、Constructor、Method、Field
  • Problems
  • Java 获取 Excel 中工作表的名称 - 指南
  • 2025年现代风格卫生间隔断生产厂家权威推荐榜单:易清洁卫生间隔断/欧式卫生间隔断/养老院卫生间隔断源头厂家精选