题意:
给了a数组的递推式,问所有满足1<=i<=n且i与m互素的ai之和
思路:
由a的递推式可以很容易地得到ai=i*(i+1)
求所有满足条件的数不好求,我们可以用所有的减去不满足条件的,即与m不互素的数贡献的a值
根据算数基本定理将m分解,与m不互素的就是至少有其中一个因子,算所有的所以要容斥
对于每个因子积sum,会形成sum,2*sum,3*sum...[n/sum]*sum这些不互素的数,
设k=[n/sum]
则对答案的贡献值是
sum*(sum+1)+2sum*(2sum+1)+3sum*(3sum+1)+...ksum*(ksum+1)
=(sum+2sum+3sum+...ksum)+(sum*sum+2sum*2sum+3sum*3sum+...ksum*ksum)
=sum * k*(1+k)/2 + sum*sum * k*(k+1)*(2k+1)/6
然后容斥一下就可以了
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define mod 1000000007
ll prime[10100];
int pl=0;
bool vis[10100];
ll n,m;
void getprime()
{
for(ll i=2;i<10010;i++)
{
if(vis[i]==false)
{
prime[++pl]=i;
}
for(int j=1;j<=pl&&i*prime[j]<10010;j++)
{
vis[i*prime[j]]=true;
if(i%prime[j]==0)
break;
}
}
}
ll num[15];
int tot;
void bre(ll n)
{
tot=0;
for(int i=1;i<=pl&&prime[i]*prime[i]<=n;i++)
{
if(n%prime[i]==0)
{
num[tot++]=prime[i];
while(n%prime[i]==0)
{
n/=prime[i];
}
}
if(n==1)
break;
}
if(n!=1)
{
num[tot++]=n;
}
}
ll inv2,inv3,inv6;
ll fpow(ll a,ll b)
{
ll ans=1;
ll tmp=a%mod;
while(b)
{
if(b&1)
ans=ans*tmp%mod;
tmp=tmp*tmp%mod;
b/=2;
}
return ans;
}
void solve()
{
ll ans=0;
for(int i=0;i<(1<<tot);i++)
{
int cnt=0;
ll sum=1;
for(int j=0;j<tot;j++)
{
if(i&(1<<j))
{
cnt++;
sum*=num[j];
}
}
ll k=n/sum;
sum%=mod;
ll p=(1+k)*k%mod*inv2%mod*sum%mod;
ll q=k*(k+1)%mod*(2*k+1)%mod*inv6%mod*sum%mod*sum%mod;
if(cnt&1)
{
ans-=p;
if(ans<0)
ans+=mod;
ans-=q;
if(ans<0)
ans+=mod;
}
else
{
ans=(ans+p);
if(ans>mod)
ans-=mod;
ans+=q;
if(ans>mod)
ans-=mod;
}
}
printf("%lld\n",ans);
}
int main()
{
getprime();
inv2=fpow(2,mod-2);
inv6=fpow(6,mod-2);
while(scanf("%lld%lld",&n,&m)!=EOF)
{
bre(m);
solve();
}
}