# BZOJ 2693 jzptab ——莫比乌斯反演

$ans=\sum_{d<=n}d*\sum_{i<=\lfloor n/d \rfloor} i^2 *\mu(i)* Sum(\lfloor \frac {n}{i*d} \rfloor,\lfloor \frac {m}{i*d} \rfloor)$

$ans=\sum_{T<=n} Sum(\lfloor \frac {n}{T}\rfloor,\lfloor \frac {m}{T}\rfloor)\sum_{i \mid T} T*i*\mu(i)$

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define F(i,j,k) for (int i=j;i<=k;++i)
#define D(i,j,k) for (int i=j;i>=k;--i)
#define ll long long
#define md 100000009
#define maxn 10000005

int n,m,t,h[maxn],pr[maxn],top=0;
bool vis[maxn];

void init()
{
memset(vis,false,sizeof vis);
h[1]=1;
F(i,2,maxn-1)
{
if (!vis[i])
{
pr[++top]=i;
h[i]=((i-(ll)i*i)%md+md)%md;
}
F(j,1,top)
{
if ((ll)i*pr[j]>=maxn) break;
vis[i*pr[j]]=true;
if (i%pr[j]==0)
{
h[i*pr[j]]=((ll)h[i]*pr[j])%md;
break;
}
h[i*pr[j]]=((ll)h[i]*h[pr[j]])%md;
}
}
F(i,2,maxn-1)
h[i]=((ll)h[i-1]+h[i])%md;
}

ll Sum(int n,int m)
{
n%=md; m%=md;
n=((ll)n*(n+1)/2)%md;
m=((ll)m*(m+1)/2)%md;
return ((ll)n*m)%md;
}

void solve(int n,int m)
{
if (n>m) swap(n,m);
ll ret=0;
for (int i=1,last=0;i<=n;i=last+1)
{
last=min(n/(n/i),m/(m/i));
ret=(ret+((ll)h[last]-h[i-1])*Sum(n/i,m/i))%md;
}
ret+=md; ret%=md;
printf("%lld\n",ret);
}

int main()
{
init();
scanf("%d",&t);
while (t--)
{
scanf("%d%d",&n,&m);
solve(n,m);
}
}


posted @ 2017-03-22 08:23  SfailSth  阅读(162)  评论(0编辑  收藏  举报