您的位置:首页 > 其它

bzoj2154: Crash的数字表格

2016-03-15 19:56 302 查看

依题意:d=gcd(i,j)d=gcd(i,j)

Ans=∑ni=1∑mj=1Lcm(i,j)=∑ni=1∑mj=1id∗jd∗dAns=\sum_{i=1}^{n}\sum_{j=1}^{m}Lcm(i,j)=\sum_{i=1}^{n}\sum_{j=1}^{m}\frac{i}{d}*\frac{j}{d}*d

⇒Ans=∑min(n,m)d=1d∗∑⌊nd⌋i=1∑⌊md⌋j=1i∗j|gcd(i,j)=1\Rightarrow Ans=\sum_{d=1}^{min(n,m)}d*\sum_{i=1}^{\left \lfloor \frac{n}{d} \right \rfloor} \sum_{j=1}^{\left \lfloor \frac{m}{d} \right \rfloor}i*j|gcd(i,j)=1

⇒Ans=∑min(n,m)d=1d∗∑⌊nd⌋i=1∑⌊md⌋j=1i∗j∗∑p|i,p|jμ(p)\Rightarrow Ans=\sum_{d=1}^{min(n,m)}d*\sum_{i=1}^{\left \lfloor \frac{n}{d} \right \rfloor} \sum_{j=1}^{\left \lfloor \frac{m}{d} \right \rfloor}i*j*\sum_{p|i,p|j}\mu(p)

⇒Ans=∑min(n,m)d=1d∗∑⌊min(nd,md)⌋p=1μ(p)∗p2∗∑⌊ndp⌋i=1∑⌊mdp⌋j=1i∗j\Rightarrow Ans=\sum_{d=1}^{min(n,m)}d*\sum_{p=1}^{\left \lfloor min(\frac{n}{d},\frac{m}{d})\right \rfloor}\mu(p)*p^{2}*\sum_{i=1}^{\left \lfloor \frac{n}{dp} \right \rfloor} \sum_{j=1}^{\left \lfloor \frac{m}{dp} \right \rfloor}i*j

枚举d,对一段d有⌊nd⌋和⌊md⌋\left \lfloor \frac{n}{d} \right \rfloor 和\left \lfloor \frac{m}{d} \right \rfloor不变,O(n−√)O(\sqrt n)。同理枚举p,总复杂度O(n)O(n)。

感谢lych

#include<iostream>
#include<cstdio>
#define N 10000005
#define mo 20101009
#define ll long long
using namespace std;
ll n,m,Ans,mu
,b
,f
;
void getMob()
{
mu[1]=1;
ll l=0;
for (ll i=2;i<=m;i++)
{
if (f[i]==0) mu[i]=-1,b[++l]=i;
for (ll j=1;j<=l;j++)
{
ll t=i*b[j];
if (t>m)break;
f[t]=1;
if (i%b[j]==0) {mu[t]=0;break;}
mu[t]=-mu[i];
}
}
for (ll i=1;i<=m;i++)
mu[i]=(mu[i-1]+mu[i]*i*i)%mo;
}
ll Get(ll a,ll b)
{
a=a*(1+a)/2%mo;
b=b*(1+b)/2%mo;
return a*b%mo;
}
int main()
{
scanf("%lld%lld",&n,&m);
if (n>m) swap(n,m);
getMob();
for (ll d=1,lastd;d<=n;d=lastd+1)
{
lastd=min(n/(n/d),m/(m/d));
ll sum=0,m1=m/d,n1=n/d;
for (ll p=1,lastp;p<=n1;p=lastp+1)
{
lastp=min(n1/(n1/p),m1/(m1/p));
sum+=(mu[lastp]-mu[p-1])*Get(n1/p,m1/p)%mo;
sum=sum%mo;
}
Ans=(Ans+((d+lastd)*(lastd-d+1)/2)%mo*sum%mo)%mo;
}
printf("%lld\n",(Ans%mo+mo)%mo);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: