思考:
明显题意就是说每次讲数组分开,以(minn+maxn)/2分,然后是否在分的过程中会出现某个value。明显既然是D题,首先不会去想暴力,而是找一下线性的方法,但是思考片刻没有思路。但是想到n范围只有1e5,每次都是分一半,那么dfs下来也就是log2的复杂度。所以直接dfs即可,也就是暴力,但是要注意dfs中l和r的关系,也就是return条件。
结论:
直接dfs搜一遍即可
代码:
#include<iostream>
#include<cstring>
#include<string>
#include<math.h>
#include<algorithm>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<set>
//#pragma GCC optimize(2)
#define eps 1e-9
#define fi first
#define se second
#define pb push_back
#define db double
#define ll long long
#define PII pair<int,int >
#define cin(x) scanf("%d",&x)
#define cout(x) printf("%d ",x)
#define mem(a,b) memset(a,b,sizeof(a))
#define IOS std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
#define int ll
using namespace std;
const int N = 5e5,M = 2000;
const int mod = 1e9+7;
const int inf = 0x3f3f3f3f;
const double pai = acos(-1);
int T,n,m;
int va[N];
set<int > s;
void dfs(int l,int r);
signed main()
{
IOS;
cin>>T;
while(T--)
{
cin>>n>>m;
for(int i=1;i<=n;i++) cin>>va[i];
sort(va+1,va+1+n);
s.clear();
dfs(1,n);
while(m--)
{
int x;
cin>>x;
if(s.count(x)) cout<<"Yes\n";
else cout<<"No\n";
}
}
return 0;
}
void dfs(int l,int r)
{
int sum = 0,minn = inf,maxn = 0,val = 0;
for(int i=l;i<=r;i++)
{
sum += va[i];
minn = min(minn,va[i]);
maxn = max(maxn,va[i]);
}
s.insert(sum);
int mid = (maxn+minn)/2;
for(int i=l;i<=r;i++)
{
if(va[i]<=mid) val = i;
else break;
}
if(val==0||val==r) return ;
dfs(l,val);
dfs(val+1,r);
}
总结:
当找不到线性的思路时,就暴力,还有一些优化。