大意:
“给你一个有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;
}