同BZOJ 2154 但是需要优化
$ans=sum_{d<=n}d*sum_{i<=lfloor n/d floor} i^2 *mu(i)* Sum(lfloor frac {n}{i*d} floor,lfloor frac {m}{i*d} floor)$
如果我们设$T=i*d$
$ans=sum_{T<=n} Sum(lfloor frac {n}{T} floor,lfloor frac {m}{T} floor)sum_{i mid T} T*i*mu(i)$
如果我们能计算出 $sum_{i mid T} T*i*mu(i)$的前缀和 我们就可以在Theta (n)的时间内解决这个问题
它是积性函数,当$pr[j] mid i$的时候,新加入的$pr[j]$对$mu$没有贡献(均为0)只有$T$的部分发生了改变所以乘一个$pr[j]$就可以了
然后就可以$Theta (Tsqrt n)$解决了
#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 ",ret); } int main() { init(); scanf("%d",&t); while (t--) { scanf("%d%d",&n,&m); solve(n,m); } }