Codeforece-689-div2

DIV2-D

思考:
明显题意就是说每次讲数组分开,以(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);
}

总结:
当找不到线性的思路时,就暴力,还有一些优化。

上一篇:篮球即时比分api接口调用示例代码


下一篇:689 三个无重叠子数组的最大和(动态规划-递推)