Solution:SP8099(TABLE - Crash's number table)
Argon_Cube · · 题解
- 【题目链接】
Link:SP8099
- 【关于此题】
以及此题只能交 C++98。
- 【解题思路】
求
套路地转换
枚举
枚举
下取整想必都知道是怎么来的。这个时候套
交换求和顺序,先枚举
其中
然后……感觉枚举两层不太可做?别担心,我们有除法分块。众所周知
所以我们最内层的柿子可以先对
看起来复杂度在
不过,这里除法分块
- 【代码实现】
#include <iostream>
#include <bitset>
using namespace std;
long long mu_square[10000001];
int primes[664580];
bitset<10000001> prime;
const long long moder=20101009;
inline long long sum(long long num)
{
return (num*num+num)%moder*10050505%moder;
}
int main(int argc,char *argv[],char *envp[])
{
ios::sync_with_stdio(false);
cin.tie(0);
long long n,m,cntprime=0,lim;
cin>>n>>m,lim=min(n,m);
mu_square[1]=1;
for(int i=2;i<=lim;i++)
{
if(!prime[i])
primes[++cntprime]=i,mu_square[i]=moder-1ll*i*i%moder;
for(int j=1;j<=cntprime&&i*primes[j]<=lim;j++)
{
prime[i*primes[j]]=true;
if(!(i%primes[j]))
{
mu_square[i*primes[j]]=0;
break;
}
mu_square[i*primes[j]]=mu_square[i]*mu_square[primes[j]]%moder;
}
}
for(int i=2;i<=lim;i++)
mu_square[i]=(mu_square[i]+mu_square[i-1])%moder;
long long ans=0;
for(long long left_r=1,right_r;left_r<=lim;left_r=right_r+1)
{
right_r=min(n/(n/left_r),m/(m/left_r));
long long blc_szn=n/left_r,blc_szm=m/left_r,inner_ans=0;
for(long long left_d=1,right_d;left_d<=lim/left_r;left_d=right_d+1)
{
right_d=min(blc_szn/(blc_szn/left_d),blc_szm/(blc_szm/left_d));
inner_ans=(inner_ans+(mu_square[right_d]-mu_square[left_d-1]+moder)%moder*sum(n/left_r/left_d)%moder*sum(m/left_r/left_d)%moder)%moder;
}
ans=(ans+inner_ans*(sum(right_r)-sum(left_r-1)+moder)%moder)%moder;
}
cout<<ans;
return 0;
}