CF1702F 题解
思路
初看这一题,这题难搞的地方就在于有两种操作,所以我们可以考虑先做完一种操作,再去单独地做第二种。我们可以发现,先把 替换成 ,再把 替换为 时,操作前和操作后的 值不变,因为这时的向下取整不起作用;但先把 替换为 ,再把 替换成 后,操作前后的 就不一定相等了。所以,我们就可以考虑先做第一种操作,再做第二种操作。
第一种操作并不是单纯地把 不断乘 ,而是把所有 和 都不断除以 ,直到所有数变为奇数为止。这时候,我们的第二种操作就可以开始了。
第二种操作也不能普通操作,否则太慢了。我们需要操作的是所有 中最大的一个 。我们需要拿 中最大的数 与它作比较,分类考虑:
- 当 时,由于这时 是单调不减的了,所以直接无解;
- 当 时,我们直接把 进行一次操作(除以 )即可;
- 当 时,这时候我们直接把 和 都删掉即可。
这里每次要求 和 ,我们可以使用 STL 的优先队列 快速解决。
代码
# include <bits/stdc++.h>
using namespace std;
int t, n, m, x;
priority_queue <int> q1, q2;
void clear (priority_queue <int>& q) {
while (! q.empty ())
q.pop ();
return ;
}
int main () {
ios::sync_with_stdio (0);
cin.tie (0);
cout.tie (0);
cin >> t;
while (t --) {
cin >> n;
clear (q1), clear (q2); //手动清空优先队列
for (int i = 0; i < n; ++ i) {
cin >> x;
while (! (x & 1)) //不断除以 2
x >>= 1;
q1.push (x);
}
for (int i = 0; i < n; ++ i) {
cin >> x;
while (! (x & 1))
x >>= 1;
q2.push (x);
}
while (! q1.empty ())
if (q1.top () < q2.top ())
q2.push (q2.top () >> 1), q2.pop (); //记得 pop
else if (q1.top () > q2.top ()) {
cout << "NO\n";
goto END; //goto 是个好东西,可以直接跳转到 END 继续执行
} else
q1.pop (), q2.pop ();
cout << "YES\n"; //有解
END: ;
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】