Codeforces Round #805 (Div. 3)
比赛链接
Codeforces Round #805 (Div. 3)
F. Equate Multisets
给出两个等长的 multiset \(a\) 和 \(b\),每次操作可以把 \(b\) 中的一个元素乘 2 或者除以 2 ,要求判断能否通过 操作 \(\boldsymbol{a}\) 和 \(b\) 能否相等
解题思路
贪心
将 \(a\) 中的所有数变为奇数,因为后面 \(b\) 可以除 \(2\) 抵消这些影响,另外每次操作都取 \(b\) 中的最大数进行操作,如果该最大数出现在 \(a\) 中的话,则该数一定要在 \(a\) 和 \(b\) 中删除,由于该数在 \(b\) 中是最大的,且只能除(由于 \(a\) 中的数都为奇数),如果该数不删除的话,后面可能对应不上该数,故该数能删必须删,如果不能删除,则需除 \(2\),直到 \(b\) 中的数删完或者全为 \(1\) 为止
设 \(b\) 中出现的最大数为 \(w\),则:
- 时间复杂度:\(O(n(logw+logn))\)
代码
// Problem: F. Equate Multisets
// Contest: Codeforces - Codeforces Round #805 (Div. 3)
// URL: https://codeforces.com/contest/1702/problem/F
// Memory Limit: 256 MB
// Time Limit: 4000 ms
//
// Powered by CP Editor (https://cpeditor.org)
// %%%Skyqwq
#include <bits/stdc++.h>
//#define int long long
#define help {cin.tie(NULL); cout.tie(NULL);}
#define pb push_back
#define fi first
#define se second
#define mkp make_pair
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;
template <typename T> bool chkMax(T &x, T y) { return (y > x) ? x = y, 1 : 0; }
template <typename T> bool chkMin(T &x, T y) { return (y < x) ? x = y, 1 : 0; }
template <typename T> void inline read(T &x) {
int f = 1; x = 0; char s = getchar();
while (s < '0' || s > '9') { if (s == '-') f = -1; s = getchar(); }
while (s <= '9' && s >= '0') x = x * 10 + (s ^ 48), s = getchar();
x *= f;
}
int t,n,x;
int main()
{
for(cin>>t;t;t--)
{
cin>>n;
multiset<int> a,b;
for(int i=1;i<=n;i++)
{
cin>>x;
while(x%2==0)x/=2;
a.insert(x);
}
for(int i=1;i<=n;i++)
{
cin>>x;
b.insert(x);
}
while(b.size())
{
int x=*b.rbegin();
if(a.count(x))a.erase(a.find(x)),b.erase(b.find(x));
else
{
if(x==1)break;
b.erase(b.find(x));
b.insert(x>>1);
}
}
puts(b.size()?"NO":"YES");
}
return 0;
}