T2
题解
前排鸣谢LCR小姐姐QAQ
首先暴力欧拉筛模拟这个过程就是27pts的
70pts就是化柿子+卡常数
我们可以发现 f(n)=(px11+1)(px22+1)...(pxkk+1) f ( n ) = ( p 1 x 1 + 1 ) ( p 2 x 2 + 1 ) . . . ( p k x k + 1 )
那么他的形式就大概是 f(a1)f(a2)...f(ak) f ( a 1 ) f ( a 2 ) . . . f ( a k ) 类似这个样子,然后我们可以枚举 f(ij)=f(i)f(j) f ( i j ) = f ( i ) f ( j ) ,只要ij<=n那么就是我们要求的答案的一部分,即f(ij),容斥一下答案也就是 ∑ab<=n[(a,b)=1]a ∑ a b <= n [ ( a , b ) = 1 ] a
化个柿子
然后反演
套路的枚举d
i可以枚举d的倍数即i=id
我们可以发现当d^2>n的时候这个值是0了,没有意义,而且当i>n/d^2的时候后面的柿子也是0,那么
这样加上分块优化可以获得60+的好成绩QAQ(其实剩下的是被卡常了
然后100pts的话
前排鸣谢zyb dalao
然后我们可以强制a < b,这样只要在后面加的时候加上a,b就好了
然后莫比乌斯反演
(当然d是从后面的a+b提出来的,因为后面的a,b枚举的都是d的倍数了)
最后一个Σ是O(1)的,前面的是标准的
O(n−−√logn−−√)
O
(
n
l
o
g
n
)
,卡完常数之后可以通过此题
卡常技巧:在%mod的时候,可以开一个unsigned longlong,每8次取一次%,这样似乎会快很多QAQ
代码
#include <cstdio>
#include <iostream>
#include <cmath>
#define LL long long
#define uli unsigned long long
using namespace std;
const int N=10000005;
const LL INF=8e18;
int mod,mu[N],pri[N],tot;bool ss[N];LL n,up;
void pre()
{
mu[1]=1;
for (int i=2;i<=up;i++)
{
if (!ss[i]) pri[++tot]=i,mu[i]=-1;
for (int j=1;j<=tot && pri[j]*i<=up;j++)
{
ss[pri[j]*i]=1;
if (i%pri[j]==0) break;
mu[pri[j]*i]=-mu[i];
}
}
}
LL ksm(LL a,LL k)
{
LL ans=1;
for (;k;k>>=1,a=a*a%mod)
if (k&1) ans=ans*a%mod;
return ans;
}
int main()
{
freopen("sum.in","r",stdin);
freopen("sum.out","w",stdout);
scanf("%lld%d",&n,&mod);
up=sqrt(n);pre();LL ans=0;
for (LL d=1;d<=up;d++)
if (mu[d])
{
LL ok=0;LL sb=up/d,lx=n/d/d;
for (LL a=1;a<=sb;a++)
{
LL t=lx/a%mod;
ok+=(uli)(t-a)*(t+a*3+1);
if (ok>INF) ok%=mod;
}
ans+=ok%mod*d*mu[d]%mod;
}
ans=ans%mod*ksm(2,mod-2)%mod;
ans++;
printf("%lld",(ans+mod)%mod);
}