题意
现在有
T
T
T个询问,每个询问给你三个整数
n
,
m
,
a
n,m,a
n,m,a,
求对于所有
1
<
=
i
<
=
n
,
1
<
=
j
<
=
m
,
1
<
=
g
c
d
(
i
,
j
)
<
=
a
1<=i<=n,1<=j<=m,1<=gcd(i,j)<=a
1<=i<=n,1<=j<=m,1<=gcd(i,j)<=a的
i
,
j
i,j
i,j的
∑
l
c
m
(
i
,
j
)
\sum lcm(i,j)
∑lcm(i,j)值。
对1e9+7取模。
这是出题人的题解
在考试的时候在subtask2上推到了倒数第2步(然后还实现错了),但是没有更进一步,这里实际上是把
p
p
p直接当做
d
k
dk
dk来枚举,然后再枚举
d
,
注
意
此
时
d
一
定
是
p
的
因
数
d,注意此时d一定是p的因数
d,注意此时d一定是p的因数
对于
s
u
b
t
a
s
k
3
subtask3
subtask3,树状数组具体含义:
c
[
p
]
c[p]
c[p]表示
p
p
p的最后一个和式的值.
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
const int kq=250000002;
const int mod=1e9+7;
inline int read(){
char c=getchar();int t=0,f=1;
while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
while(isdigit(c)){t=(t<<3)+(t<<1)+(c^48);c=getchar();}
return t*f;
}
int t,n,m,a;
int mu[maxn],p[maxn],cnt,vis[maxn],alfa[maxn];
inline int am(int x){
return x>=mod?x-mod:x;
}
void get(){
mu[1]=1;
for(int i=2;i<=1e5;i++){
if(!vis[i]){
p[++cnt]=i;mu[i]=-1;
}
for(int j=1;i*p[j]<=1e5&&j<=cnt;j++){
vis[i*p[j]]=1;
mu[i*p[j]]=mu[i]*mu[p[j]];
if(i%p[j]==0){
mu[i*p[j]]=0;
break;
}
}
}
for(int i=1;i<=1e5;i++){
mu[i]=1ll*mu[i]*i%mod*i%mod;
mu[i]=am(mu[i]+mod);
}
}
struct node{
int n,m,a,id;
}q[maxn];
int c[maxn],out[maxn];
bool cmp(node a,node b){
return a.a<b.a;
}
inline int lowbit(int x){
return x&(-x);
}
inline void add(int pos,int val){
for(int i=pos;i<=1e5;i+=lowbit(i))c[i]=am(c[i]+val);
}
inline int query(int pos){
int ans=0;
for(;pos;pos-=lowbit(pos)){ans=am(ans+c[pos]);}
return ans;
}
inline int sum(int x){
return 1ll*x*(x+1)/2%mod;
}
int main(){
//freopen("a.in","r",stdin);
//freopen("a2.out","w",stdout);
t=read();
get();
for(int i=1;i<=t;i++){
q[i].n=read();q[i].m=read();q[i].a=read();q[i].id=i;
}
sort(q+1,q+1+t,cmp);
for(int i=1;i<=t;i++){
n=q[i].n,m=q[i].m;
if(n<m)swap(n,m);
int l=1,r,ans=0;
for(int j=q[i-1].a+1;j<=q[i].a;j++){
for(int k=j;k<=1e5;k+=j){
add(k,1ll*j*mu[k/j]%mod);
}
}
for(;l<=m;l=r+1){
r=min(n/(n/l),m/(m/l));
int sum1=sum(n/l),sum2=sum(m/l);
ans=am(ans+1ll*sum1*sum2%mod*(query(r)-query(l-1)+mod)%mod);
ans=am(ans+mod);
}
out[q[i].id]=ans;
}
for(int i=1;i<=t;i++)
printf("%d\n",out[i]);
return 0;
}