牛客月赛40

来点gcd
题意:
给定一个含有 n n n 个数的序列, m m m 次询问,每次查询给出一个整数 x x x,问是否能在序列中选出一些数,满足这些数的 g c d = x gcd=x gcd=x,如果只选出一个数,那么 g c d gcd gcd 就等于这个数。
思路:
首先要使选出的数的 g c d = x gcd=x gcd=x,那么这些数一定都是 x x x 的倍数。考虑到 n < = 2000 n<=2000 n<=2000,可以预处理所有答案,对于要查询的答案 i i i,枚举 i i i 的倍数,如果这个倍数出现过就进行 g c d gcd gcd,扫完一遍判断 g c d gcd gcd 是否为 i i i,如果不为 i i i,那么无论怎么选也不会选出 g c d = i gcd=i gcd=i 的序列。
code:

#include<bits/stdc++.h>
#define endl '\n'
#define ll long long
#define ull unsigned long long
#define ld long double
using namespace std;
const int maxn = 1e6 + 9;
const int mod = 1e9 + 7;
ll n, m;
bool v[maxn], ans[maxn];
void work()
{
	scanf("%lld %lld", &n, &m);
	for(int i = 1; i <= n; ++i) v[i] = ans[i] = 0;
	for(int i = 1; i <= n; ++i){
		int x;scanf("%d", &x);v[x] = 1;
	}
	for(int i = 1; i <= n; ++i){
		ll x = 0;
		for(ll j = i; j <= n; j += i) if(v[j])
			x = __gcd(x, j);
		if(x == i) ans[i] = 1;
	}
	while(m--)
	{
		int x;scanf("%d", &x);
		if(ans[x]) printf("YES\n");
		else printf("NO\n");
	}
}

int main()
{
//	ios::sync_with_stdio(0);
	int TT;cin>>TT;while(TT--)
	work();
	return 0;
}

上一篇:Day_40_JavaScript数组、函数、对象、常用内置对象


下一篇:拓变论 对 质能公式 的 推导 会是 一篇 丰富有趣 的 论文