标签:cnt ch gcd int sum CF585E Vitalik mu Present
给定一个集合a,要求一个集合S和一个数x,满足\(x\notin S\),且\(\gcd(x,S)=1,\gcd(S)>1\),求方案数
设\(cnt_T\)表示T的倍数的个数,那么此时\(\gcd(S)>1\)的限制可以忽略
对于每个集合S,我们直接计算\((n-cnt_S)* (2^{cnt_S}-1)\)会有重复和非法,考虑容斥
设\(\gcd(S,x)=k\),我们要做的就是使\(k>1\)的计算0次,\(k=1\)的计算一次
考虑实际情况,(S,x)会被\(d|\gcd(S)且d\nmid x\)计算
因为在枚举\(d|\gcd(S)\),对于x中含有而\(\gcd(S)\)中不含的质因子不会计算,那么又可以写成
\(d|\gcd(S)且d\nmid k\),写成式子是\(\sum_{d|\gcd(S)}\mu(d)-\sum_{d\nmid k}\mu(d)\)
由于\(\gcd(S)>1\),故若k=1,值为-1,k!=1则为0
那么写成\(-\mu(d)\)就行了
答案就是\(\sum_{i=1}^{\max(a)}-\mu(i)* (n-cnt_i)* (2^{cnt_i}-1)\)
代码
#include<bits/stdc++.h>
using namespace std;
const int N=1e7+11;
const int mod=1e9+7;
bool fp[N];
int n;
int mu[N];
int p[N],num;
int mi[N],c[N];
inline int max_(int a,int b){return a>b?a:b;}
inline void md(int &x){if(x>=mod)x-=mod;return;}
inline int read()
{
int s=0;
char ch=getchar();
while(ch>'9'||ch<'0') ch=getchar();
while(ch>='0'&&ch<='9') s=(s<<1)+(s<<3)+(ch^48),ch=getchar();
return s;
}
void pre()
{
fp[0]=fp[1]=1;
mu[1]=1;
for(int i=2;i<=1e7;++i)
{
if(!fp[i])p[++num]=i,mu[i]=-1;
for(int j=1;j<=num&&p[j]*i<=1e7;++j)
{
fp[p[j]*i]=1;
if(i%p[j]==0) {mu[i*p[j]]=0;break;}
else mu[i*p[j]]=-mu[i];
}
}
return;
}
signed main()
{
pre();
n=read();
mi[0]=1;
int maxx=0;
for(int x,i=1;i<=n;++i) x=read(),mi[i]=mi[i-1]*2%mod,++c[x],maxx=max_(maxx,x);
int ans=0;
for(int cnt,i=1;i<=maxx;++i)
{
cnt=0;
for(int j=i;j<=maxx;j+=i) cnt+=c[j];
md(ans+=1ll*(mod-mu[i])*(n-cnt)%mod*(mi[cnt]-1)%mod);
}
cout<<ans<<endl;
return 0;
}
标签:cnt,ch,gcd,int,sum,CF585E,Vitalik,mu,Present 来源: https://www.cnblogs.com/sitiy/p/15538260.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。