- 题目链接:https://nanti.jisuanke.com/t/31448
- 题意:
an=⎧⎩⎨⎪⎪⎪⎪⎪⎪⎪⎪0,2,3an−1−an−22+n+1,n=0n=1n>1 a n = { 0 , n = 0 2 , n = 1 3 a n − 1 − a n − 2 2 + n + 1 , n > 1
在1~n中找出所有与m互质的数: b1,b2,…,bp b 1 , b 2 , … , b p , 计算 ∑pi=1abi ∑ i = 1 p a b i
1 <= n, m <= 1e8 - 思路:
- 首先时限1s,n和m都为1e8,很明显如果采用题目给的
an
a
n
的公式,连所有的
an
a
n
都求不出来,说明还有其他公式可以推出来。将
an
a
n
打表容易推出
an=n(n+1) a n = n ( n + 1 )
- 如果直接求与m互质的数,在1e8的数据范围下肯定会超时。所以采用求不互质的数,并通过公式求前n项和解决。求出m的素数因子,其任意个之间的乘积以及其倍数都是不和m互质的数。设素数因子的某个乘积为sum。则其倍数:
1sum,2sum,3sum,…,ksum
1
s
u
m
,
2
s
u
m
,
3
s
u
m
,
…
,
k
s
u
m
(k = n/sum) 都是不互质的数。代入
an
a
n
得 该sum的贡献为
sum∗k(k+1)2+sum2∗k(k+1)(2k+1)6 s u m ∗ k ( k + 1 ) 2 + s u m 2 ∗ k ( k + 1 ) ( 2 k + 1 ) 6
- ans先加上 an a n 的前n项和,在通过容斥公式除去不互质的数的贡献。
- 首先时限1s,n和m都为1e8,很明显如果采用题目给的
an
a
n
的公式,连所有的
an
a
n
都求不出来,说明还有其他公式可以推出来。将
an
a
n
打表容易推出
#include <bits/stdc++.h>
#define pi acos(-1.0 )
#define fastio ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int INF = 0x3f3f3f3f; // ²»ÄܼӸººÅ£¡£¡£¡
const LL LL_INF = 0x3f3f3f3f3f3f3f3f;//4e18 ~= 2^62
const int maxn =10000 + 10;
const LL mod = 1e9+7;
LL inv2 = 500000004;
LL inv6 = 166666668;
int pl=0;
LL prime[maxn];
bool vis[maxn];
void getprime()
{
for(int i=2;i<maxn;i++)
{
if(vis[i]==false)
{
prime[++pl]=i;
}
for(int j=1;j<=pl&&i*prime[j]<maxn;j++)
{
vis[i*prime[j]]=true;
if(i%prime[j]==0)
break;
}
}
}
LL fac[15];
int tot;
void getfactor(LL n)
{
tot=0;
for(int i=1;i<=pl&&prime[i]*prime[i]<=n;i++)
{
if(n%prime[i]==0)
{
fac[tot++]=prime[i];
while(n%prime[i]==0)
{
n/=prime[i];
}
}
if(n==1)
break;
}
if(n!=1)
{
fac[tot++]=n;
}
}
LL solve(int n)
{
LL ans = 0;
for(int i=0; i<(1<<tot); i++){
LL sum=1, cnt=0;
for(int j=0; j<tot; j++){
if(i&(1<<j)){
cnt++;
sum = (sum * fac[j]) %mod;
}
}
LL k = n/sum;
LL p = k*(k+1)%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 = ((ans - p - q)%mod + mod)%mod;
}
else ans = (ans + p + q)%mod;
}
return ans;
}
int main()
{
getprime();
int n, m;
while(~scanf("%d%d", &n, &m)){
getfactor(m);
printf("%lld\n", solve(n));
}
}