bzoj2154: Crash的数字表格

9 篇文章 0 订阅

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

Ans=ni=1mj=1Lcm(i,j)=ni=1mj=1idjdd

Ans=min(n,m)d=1dndi=1mdj=1ij|gcd(i,j)=1

Ans=min(n,m)d=1dndi=1mdj=1ijp|i,p|jμ(p)

Ans=min(n,m)d=1dmin(nd,md)p=1μ(p)p2ndpi=1mdpj=1ij

枚举d,对一段d有 ndmd 不变, O(n) 。同理枚举p,总复杂度 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[N],b[N],f[N];
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; 
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值