bzoj2693: jzptab

传送门
@jzq233jzq
没看过2154的右转

=d=1i=1ndij=1mdj(gcd(i,j)==1)

然后再化开。
=d=1db=1μ(b)b2i=1ndbij=1mdbj

D=db
=D=1i=1nDij=1mDjD|bDbμ(b)b2

然后设 f(x)=jD|bDbmu(b)b2
可以发现 f(x) 是积性函数。
线性筛一发+分块枚举D水过。

#include
#include
#include
#include
#include
#include
#define ll long long
using namespace std;
const ll mo=100000009;
const int N=10000005;
ll h[N],ans;
int pri[N/10],T,n,m,tot;
bool fl[N];
ll sum(ll x,ll y){
    ll s1=x*(x+1)/2%mo;
    ll s2=y*(y+1)/2%mo;
    return s1*s2%mo; 
}
int main(){
    h[1]=1;
    for (int i=2;iif (!fl[i]){
            pri[++tot]=i;
            h[i]=(i-1ll*i*i%mo+mo)%mo;
        }
        for (int j=1;pri[j]*i*i]=1;
            if (i%pri[j]==0){
                h[pri[j]*i]=pri[j]*h[i]%mo;
                break;
            }
            h[pri[j]*i]=h[pri[j]]*h[i]%mo;
        }
    }
    for (int i=1;i1])%mo;
    scanf("%d",&T);
    while (T--){
        scanf("%d%d",&n,&m);
        ans=0;
        if (n>m) swap(n,m);
        for (int i=1,j;i<=n;i=j+1){
            j=min(n/(n/i),m/(m/i));
            ans=(ans+sum(n/i,m/i)*(h[j]-h[i-1])%mo+mo)%mo; 
        }
        printf("%lld\n",ans);
    }
} 

你可能感兴趣的:(辣鸡八中,数论)