再数17(搜索+容斥)

大意:

“给你一个有n个正整数的数列{an}。一个正整数x若满足在数列{an}中存在一个正整数ai,使x≡17(mod ai),那么x就是一个‘cost数’。请问1到m的正整数中,有多少个‘cost数’?”
输入
第一行两个正整数n和m,意义见问题描述。
第二行n个正整数,分别为数列{an}中的n个数。
输出
输出一个整数,表示1到m中“cost数”的个数。
样例输入
3 100
18 22 23
样例输出
11
提示
【数据范围】
对于20%的数据,有n≤20,m≤100,000;
另有40%的数据,n≤3,m<2^31;
对于100%的数据,有n≤30,m<231,17<ai<231。
(注:“≡”为同余符号,a≡b (mod k) 即a mod k = b mod k)

我记得讲过容斥的

奇数个lcm加,偶数个lcm减

#include<bits/stdc++.h>
#include<tr1/unordered_map>
#define ll long long
#define int long long
using namespace std;
inline int read(){
	char ch=getchar();
	int res=0;
	while(!isdigit(ch))ch=getchar();
	while(isdigit(ch)) res=(res<<1)+(res<<3)+(ch^48),ch=getchar();
	return res;
}
int n,m,a[35],ans;
inline ll gcd(ll x,ll y){
	return y==0?x:gcd(y,x%y);
}
inline ll lcm(ll x,ll y){
	return x/gcd(x,y)*y;
}
inline void dfs(int u,int sum,int k){
	if(sum>m)return;
	if(u>n)return;
	ll f=lcm(sum,a[u]);
	if(k&1)ans+=m/f;
	else ans-=m/f;
	dfs(u+1,sum,k);
	dfs(u+1,f,k+1);
}
inline bool comp(int u,int v){
	return u>v;
}
signed main(){
	n=read(),m=read();
	for(int i=1;i<=n;i++){
		a[i]=read();
	}
	if(m<=17){
		cout<<0;
		return 0;
	}
	m-=17;
	sort(a+1,a+n+1,comp);
	dfs(1,1,1);
	cout<<ans+1;
	return 0;
}
原文地址:https://www.cnblogs.com/stargazer-cyk/p/10366425.html