题解:CF1702F Equate Multisets
对于一个 $a_i$ 若可以表示成 $k \times 2^p$ 的形式,那一定可以由 $k$ 进行若干次第一个乘 $2$ 的操作得到。所以我们将所有的 $a_i$ 预处理,使其变成奇数。然后使用 map <int,int> p 统计 $a_i$ 的分布,$p_i$ 的值就相当于处理 $b$ 后该数需要出现的次数。
对于每一个 $b_i$,若 $p_{b_i}$ 大于 $0$,那么就说明 $b_i$ 可以变成某个 $a_j$。因此将 $p_{b_i} - 1$ 以作更新;否则将 $b_i$ 除以 $2$ 后向下取整,直至为 $0$。最后只要更新的次数为 $n$,就说明每一个 $b_i$ 都能分别对应一个不同的 $a_j$,此时答案为 YES。
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
| #include <iostream> #include <cstdio> #include <algorithm> #include <cmath> #include <cstring> #include <map> #define init(x) memset (x,0,sizeof (x)) #define ll long long #define ull unsigned long long #define INF 0x3f3f3f3f using namespace std; const int MAX = 2e5 + 5; const int MOD = 1e9 + 7; inline int read (); int t,n,cnt,a[MAX],b[MAX]; map <int,int> p; int main () { t = read (); while (t--) { n = read (); cnt = n; p.clear (); for (int i = 1;i <= n;++i) { a[i] = read (); while (a[i] % 2 == 0) a[i] /= 2; ++p[a[i]]; } for (int i = 1;i <= n;++i) { int x = read (); while (x) { if (p[x]) { --p[x],--cnt; break; } x /= 2; } } if (!cnt) printf ("YES\n"); else printf ("NO\n"); } return 0; } inline int read () { int s = 0;int f = 1; char ch = getchar (); while ((ch < '0' || ch > '9') && ch != EOF) { if (ch == '-') f = -1; ch = getchar (); } while (ch >= '0' && ch <= '9') { s = s * 10 + ch - '0'; ch = getchar (); } return s * f; }
|