版权声明:是自己手打的没错 https://blog.csdn.net/Mr_Treeeee/article/details/82669754
https://nanti.jisuanke.com/t/31448
题意:
给你一个F(a)的表达式,问你1到n中,与m互质的F(i)的和
POINT:
F(i)=i^2+i。
1方+2方+……+n方有公式。
1+2+……+n也有公式。那么不难发现,k方+2k方+3k方也会有公式。
那么把答案反过来求,求出1到n中与m不互质的i的F和。
可以分解质因数后用容斥求。
#include <iostream>
#include <stdio.h>
#include <math.h>
#include <algorithm>
using namespace std;
#define LL long long
const LL N = 1e5+5;
const LL mod = 1e9+7;
LL qkm(LL base,LL mi)
{
LL ans=1;
while(mi){
if(mi&1) ans=ans*base%mod;
base=base*base%mod;
mi>>=1;
}
return ans;
}
LL cal(LL x)
{
return 1LL*(1+x)*x/2%mod;
}
LL cal2(LL x)
{
LL sum=1LL*x*(x+1)%mod*(2*x+1)%mod*qkm(6,mod-2)%mod;
return sum;
}
LL p[N];
LL ans;
LL n,m,cnt;
void dfs(LL x,LL now,LL y)
{
if(y) ans-=now*now%mod*cal2(n/now)%mod+now*cal(n/now)%mod;
else ans+=now*now%mod*cal2(n/now)%mod+now*cal(n/now)%mod;
ans=ans+5*mod;ans%=mod;
for(LL i=x+1;i<=cnt;i++)
dfs(i,now*p[i],y^1);
}
int main()
{
while(~scanf("%lld%lld",&n,&m)){
ans=cal(n)+cal2(n);
cnt=0;
for(LL i=2;i*i<=m;i++){
if(m%i==0){
p[++cnt]=i;
while(m%i==0)
m=m/i;
}
}
if(m>1)
p[++cnt]=m;
for(LL i=1;i<=cnt;i++)
dfs(i,p[i],1);
printf("%lld\n",ans%mod);
}
return 0;
}