【CodeForces】915 G. Coprime Arrays 莫比乌斯反演
2024-08-27 16:08:18
【题意】当含n个数字的数组的总gcd=1时认为这个数组互质。给定n和k,求所有sum(i),i=1~k,其中sum(i)为n个数字的数组,每个数字均<=i,总gcd=1的方案数。n<=2*10^6。答案将所有sum(i)处理成一个数字后输出。
【算法】数论(莫比乌斯反演)
【题解】假设当前求sum(k),令f(i)表示gcd=i的数组方案数,F(i)表示i|gcd的数组的方案数。
因为F(x)=Σx|df(d),由莫比乌斯反演定理,f(x)=Σx|dμ(d/x)*F(d)。
又F(x)=(k/x)^n,所以f(1)=Σμ(d)*(k/d)^n,d=1~k。
初始k=1,当k++时ans+=Σd|kμ(d)*((k/d)^n-(k/d-1)^n),这个过程只需要k ln k枚举贡献答案即可,同时预处理快速幂。
复杂度O(k log n+k ln k)。
#include<cstdio>
const int N=,MOD=1e9+;
int n,m,miu[N],prime[N],mark[N],sum[N],p[N],tot,ans,ANS;
int pow(int x,int k){
if(!x)return ;
int ans=;
while(k){
if(k&)ans=1ll*ans*x%MOD;
x=1ll*x*x%MOD;
k>>=;
}
return ans;
}
int main(){
scanf("%d%d",&n,&m);
miu[]=;
for(int i=;i<=m;i++){
if(!mark[i]){miu[prime[++tot]=i]=-;}
for(int j=;j<=tot&&i*prime[j]<=m;j++){
mark[i*prime[j]]=;
if(i%prime[j]==)break;
miu[i*prime[j]]=-miu[i];
}
}
for(int i=;i<=;i++)p[i]=pow(i,n);
for(int i=;i<=m;i++){
for(int j=i;j<=m;j+=i)sum[j]=((sum[j]+1ll*miu[i]*(p[j/i]-p[j/i-]))%MOD+MOD)%MOD;
ans=(ans+sum[i])%MOD;
ANS=(ANS+(ans^i))%MOD;
}
printf("%d",ANS);
return ;
}
最新文章
- java中jdk和jre的区别
- inotify resources exhausted
- Centos 7 ASP.NET Core 1.0 Docker部署
- [置顶] Android应用开发之版本更新你莫愁
- 在CentOS下面编译WizNote Qt Project
- Jqgrid入门-使用模态对话框编辑表格数据(三)
- VLD(Visual LeakDetector)内存泄露库的使用
- NCache:最新发布的.NET平台分布式缓存系统
- Linux命令、脚本
- JavaScript面试技巧(二):JS-Web-API
- jQuery相关用法
- 使用Hexo+Github搭建属于自己的博客(进阶)
- nginx AIO机制与sendfile机制
- 97.394570112228 - Query OK, 1 row affected (43.05 sec) - the overhead of parsing and network communication
- AP与CP介绍【转】
- php5.5过渡--mysql连接
- Redis安装和部署--LINUX
- Java 创建线程的方式
- 12.24笔记(关于//UIDynamic演练//多对象的附加行为//UIDynamic简单演练//UIDynamic//(CoreText框架)NSAttributedString)
- nginx禁止对写操作timeout时retry