题解 [CF1654C] Alice and the Cake
因为在我还没有完全想到做法时 B 哥把做法喊出来了所以还是写一下
发现最初的蛋糕大小是已知的
发现第一步的切法是固定的
发现若切出了一块给定序列中有的蛋糕,可以直接从原序列中删掉这块蛋糕
发现若没有,只能按固定策略递归切下去
若切出了一个大小为 0 的蛋糕则无解
那么 dfs 树高为 log,最多有 \(n+1\) 个叶子,故复杂度 \(O(n\log n)\)
点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define N 200010
#define ll long long
#define int long long
char buf[1<<21], *p1=buf, *p2=buf;
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf, 1, 1<<21, stdin)), p1==p2?EOF:*p1++)
inline int read() {
int ans=0, f=1; char c=getchar();
while (!isdigit(c)) {if (c=='-') f=-f; c=getchar();}
while (isdigit(c)) {ans=(ans<<3)+(ans<<1)+(c^48); c=getchar();}
return ans*f;
}
int n;
int a[N], sum;
map<int, int> mp;
bool dfs(int n) {
int a=n/2, b=n-a;
if (!a || !b) return 0;
if (mp[a]) --mp[a];
else {if (!dfs(a)) return 0;}
if (mp[b]) --mp[b];
else {if (!dfs(b)) return 0;}
return 1;
}
signed main()
{
int T=read();
while (T--) {
n=read();
mp.clear(); sum=0;
for (int i=1; i<=n; ++i) {
sum+=(a[i]=read());
++mp[a[i]];
}
if (n==1) puts("YES");
else puts(dfs(sum)?"YES":"NO");
}
return 0;
}