我们定义 F(i) F ( i ) 为 i i 的约数和,题目要求的是
我们先忽略 a a 这个限制
令
⇒g(i)=∑i|dμ(di)⌊nd⌋⌊md⌋ ⇒ g ( i ) = ∑ i | d μ ( d i ) ⌊ n d ⌋ ⌊ m d ⌋
然后就有
Ans=∑ni=1F(i)g(i) A n s = ∑ i = 1 n F ( i ) g ( i )
=∑ni=1F(i)∑i|dμ(di)⌊nd⌋⌊md⌋ = ∑ i = 1 n F ( i ) ∑ i | d μ ( d i ) ⌊ n d ⌋ ⌊ m d ⌋
=∑nd=1⌊nd⌋⌊md⌋∑i|dF(i)μ(di) = ∑ d = 1 n ⌊ n d ⌋ ⌊ m d ⌋ ∑ i | d F ( i ) μ ( d i )
我们令 f(i)=∑i|dF(i)μ(di) f ( i ) = ∑ i | d F ( i ) μ ( d i )
首先线性筛或者枚举倍数来预处理出 F(i) F ( i )
然后枚举每个数更新倍数,求出 f(i) f ( i ) 的前缀和,分块就好了
考虑有了 a a 的限制,我们发现只有的 i i 才对答案有贡献
我们离线处理,按排序每次把合法的加入树状数组
就可以维护出 f(i) f ( i ) 的前缀和了,最后分块就好了
因为模数是 2 2 的整数幂,自然溢出就好了,最后要与取与
#include<cmath>
#include<cstdio>
#include<algorithm>
#define fp(i,a,b) for(int i=a,I=b;i<=I;++i)
#define fd(i,a,b) for(int i=a,I=b;i>=I;--i)
#define file(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
template<class T>inline bool chkmax(T&a,const T&b){return a<b?a=b,1:0;}
template<class T>inline bool chkmin(T&a,const T&b){return a>b?a=b,1:0;}
using namespace std;
char ss[1<<17],*A=ss,*B=ss;
inline char gc(){return A==B&&(B=(A=ss)+fread(ss,1,1<<17,stdin),A==B)?-1:*A++;}
template<class T>inline void sd(T&x){
char c;T y=1;while(c=gc(),(c<48||57<c)&&c!=-1)if(c==45)y=-1;x=c^48;
while(c=gc(),47<c&&c<58)x=(x<<1)+(x<<3)+(c^48);x*=y;
}
char sr[1<<21],z[20];int C=-1,Z;
template<class T>inline void we(T x){
if(x<0)sr[++C]=45,x=-x;
while(z[++Z]=x%10+48,x/=10);
while(sr[++C]=z[Z],--Z);sr[++C]='\n';
if(C>1<<20)fwrite(sr,1,C+1,stdout),C=-1;
}
const int N=1e5+5,P=-1u>>1;
typedef int arr[N];
struct que{
int n,m,a,id;
inline void in(){sd(n),sd(m),sd(a);if(n>m)swap(n,m);}
inline bool operator<(const que&b)const{return a<b.a;}
}a[N];
struct no{int val,pos;}f[N];
int T,M;arr c,is,pr,mu,ans,g,s;
inline bool cmp(const no&a,const no&b){return a.val<b.val;}
inline void mdy(int i,int w){for(;i<=M;i+=i&-i)c[i]+=w;}
inline int qry(int i){int w=0;for(;i;i-=i&-i)w+=c[i];return w;}
inline int sol(int n,int m){
int i=1,j=sqrt(n),s,t=0,w=0;
for(;i<=j;++i,t=s)s=qry(i),w+=(n/i)*(m/i)*(s-t);
for(t=qry(i-1);i<=n;i=j+1,t=s){
j=min(n/(n/i),m/(m/i));s=qry(j);
w+=(n/i)*(m/i)*(s-t);
}
return w;
}
int main(){
#ifndef ONLINE_JUDGE
file("s");
#endif
sd(T);fp(i,1,T)a[i].in(),a[i].id=i,chkmax(M,a[i].n);
mu[1]=f[1].val=f[1].pos=1;
fp(i,2,M){
if(!is[i])mu[i]=-1,pr[++pr[0]]=i,s[i]=f[i].val=i+1,g[i]=i;f[i].pos=i;
for(int j=1,x;j<=pr[0]&&(x=i*pr[j])<=M;++j){
is[x]=1;
if(i%pr[j])mu[x]=-mu[i],f[x].val=f[i].val*(1+pr[j]),g[x]=pr[j],s[x]=g[x]+1;
else{mu[x]=0,g[x]=g[i]*pr[j],s[x]=s[i]+g[x],f[x].val=f[i/g[i]].val*s[x];break;}
}
}
sort(f+1,f+M+1,cmp);sort(a+1,a+T+1);
for(int i=1,j=1;i<=T;++i){
for(;j<=M&&f[j].val<=a[i].a;++j)
for(int k=f[j].pos;k<=M;k+=f[j].pos)
mdy(k,f[j].val*mu[k/f[j].pos]);
ans[a[i].id]=sol(a[i].n,a[i].m);
}
fp(i,1,T)we(ans[i]&P);
fwrite(sr,1,C+1,stdout);
return 0;
}