您的位置:首页 > 其它

bzoj2693: jzptab

2017-04-11 11:03 369 查看
传送门

@jzq233jzq

没看过2154的右转

答案=∑d=1∑i=1ndi∑j=1mdj(gcd(i,j)==1)

然后再化开。

=∑d=1d∑b=1μ(b)∗b2∗∑i=1ndbi∑j=1mdbj

设D=db

则=∑D=1∑i=1nDi∑j=1mDj∗∑D|bDbμ(b)∗b2

然后设f(x)=j∗∑D|bDbmu(b)∗b2

可以发现f(x)是积性函数。

线性筛一发+分块枚举D水过。

#include<cmath>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
const ll mo=100000009;
const int N=10000005;
ll h
,ans;
int pri[N/10],T,n,m,tot;
bool fl
;
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;i<N;i++){
if (!fl[i]){
pri[++tot]=i;
h[i]=(i-1ll*i*i%mo+mo)%mo;
}
for (int j=1;pri[j]*i<N&&j<=tot;j++){
fl[pri[j]*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;i<N;i++)
h[i]=(h[i]+h[i-1])%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);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: