题解:SP6285 NGM2 - Another Game With Numbers

蓝有点过于虚高了。

Solution SP6285

Idea

因为 kk 只有 1515,考虑状压。

正难则反,我们考虑求 [1,n][1,n] 中可以被任意一个 aia_i 整除的数的数量。

显然我们可以处理出每一个集合的每个数的 lcm\operatorname{lcm}。然后你会发现可以被这个集合所有数整除的数的个数是 nlcm{S}\lfloor\dfrac{n}{\operatorname{lcm}\{S\}}\rfloor

考虑容斥:显然 ansans 是可以被含有一个数的集合的所有数整除的个数减去它们重合的部分,也就是可以被含有两个数的集合的所有数整除的个数。然后两个数的集合也有重复(三个数的集合),不断循环得到容斥式子:

  • Smod2=0|S|\mod 2=0,则 ans=ansnlcm{S}ans=ans-\lfloor\dfrac{n}{\operatorname{lcm}\{S\}}\rfloor
  • Smod2=1|S|\mod 2=1,则 ans=ans+nlcm{S}ans=ans+\lfloor\dfrac{n}{\operatorname{lcm}\{S\}}\rfloor

于是做完了。

Code

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=15;
int n,k;
ll a[N],ans;
int main(){
	scanf("%d%d",&n,&k);
	for(int i=0;i<k;i++){
		scanf("%lld",&a[i]);
	}
	for(int i=1;i<(1<<k);i++){
		ll res=1;
		int cnt=0;
		for(int j=0;j<k;j++){
			if(i&(1<<j)){
				res=res/__gcd(a[j],res)*a[j];
				cnt++;
			} 
		}
		if(cnt&1)ans+=n/res;
		else ans-=n/res;
	}
	printf("%d\n",n-ans);
	return 0;
}
posted @   Weslie_qwq  阅读(2)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示