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;
}
posted @ 2022-08-08 21:33  zyy2001  阅读(36)  评论(0编辑  收藏  举报