BZOJ 2401 陶陶的难题I 数论

667 篇文章 1 订阅

题目大意:求 Ni=1Nj=1Lcm(i,j)
一开始写了个莫比乌斯反演结果T到死。。。
Ni=1Nj=1Lcm(i,j)=Ni=1i+2Ni=1i1j=1Lcm(i,j)=Ni=1i+2Ni=1i1j=1ijGcd(i,j)=Ni=1i+2Nd=1Ndi=2i1j=1[gcd(i,j)=1]dij=Ni=1i+2Nd=1Ndi=2diiφ(i)2=Ni=1i+Nd=1Ndi=2di2φ(i)
然后O(nlogn)计算每一项,求前缀和即可
时间复杂度O(nlogn+T)
WQNMLGB的取个模能死?

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define M 1001001
using namespace std;

struct Int128{
    #define BASE 1000000000000000000ll
    long long num[2];
    void Standardization()
    {
        if(num[0]>=BASE)
            num[0]-=BASE,num[1]++;
    }
    Int128() {}
    Int128(long long _)
    {
        num[0]=_;
        num[1]=0;
        Standardization();
    }
    Int128& operator += (const Int128 &x)
    {
        num[0]+=x.num[0];
        num[1]+=x.num[1];
        Standardization();
        return *this;
    }
    friend ostream& operator << (ostream &_,const Int128 &x)
    {
        if(x.num[1])
        {
            printf("%lld%09d%09d\n",x.num[1],(int)(x.num[0]/1000000000),(int)(x.num[0]%1000000000) );
            return _;
        }
        printf("%lld\n",x.num[0]);
        return _;
    }
};

int phi[M],prime[100100],tot;
bool not_prime[M];
Int128 sum[M];

int n;

void Linear_Shaker()
{
    int i,j;
    for(i=2;i<=1000000;i++)
    {
        if(!not_prime[i])
        {
            phi[i]=i-1;
            prime[++tot]=i;
        }
        for(j=1;prime[j]*i<=1000000;j++)
        {
            not_prime[prime[j]*i]=true;
            if(i%prime[j]==0)
            {
                phi[prime[j]*i]=phi[i]*prime[j];
                break;
            }
            phi[prime[j]*i]=phi[i]*(prime[j]-1);
        }
    }
}

void Pretreatment()
{
    int i,j;
    Linear_Shaker();
    for(i=1;i<=1000000;i++)
    {
        sum[i]+=i;
        for(j=2;i*j<=1000000;j++) 
            sum[i*j]+=Int128((long long)i*j*j*phi[j]);
    }
    for(i=1;i<=1000000;i++)
        sum[i]+=sum[i-1];
}

int main()
{
    int T;
    Pretreatment();
    for(cin>>T;T;T--)
    {
        scanf("%d",&n);
        cout<<sum[n];
    }
    return 0;
}
参与评论 您还未登录,请先 登录 后发表或查看评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页

打赏作者

PoPoQQQ

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值