【BZOJ3512】 DZY Loves Math IV

12 篇文章 0 订阅

题意:(第n+1次)略

Ans(n,m)=i=1nj=1mφ(ij)s(n,m)=i=1mφ(ni)Ans(n,m)=i=1ns(i,m)1nis(n,m)=i=1mφ(ni)西|μ(n)|=1φ(nk)=d|n,d|kφ(nd)φ(k)s(n,m)=k=1nd|n,d|kφ(nd)φ(k)=d|nφ(nd)k=1mdφ(dk)=d|nφ(nd)S(d,md)|μ(n)|=0k|n使|μ(k)|=0S(n,m)=nS(k,m)kS(1,m)=m(m+1)2i=2mS(1,mi)

杜教筛大力筛吧。然后递归求就好了。参考的大师的题解
注意:要记得记搜和map!!!!还有线性筛千万不要写错了(欧拉函数筛错的斯波在这里)

#include <bits/stdc++.h>
#define ll long long
#define N 2000009
#define mod 1000000007
using namespace std;
int n,M,pri[N],pd[N],cnt,phi[N],Min[N],Ans[N],sum[N];
map<ll,int>MAP;
int S(int n,int m)
{
    if (m<=1) return phi[n*m];
    if (n==1)
    {
        if (m<N) return sum[m];
        if (Ans[M/m]!=-1) return Ans[M/m];
        ll ans=(ll)m*(m+1)/2%mod;
        for (int i=2,j;i<=m;i=j+1)
        {
            j=m/(m/i);
            if (m/i<N) ans=ans-(ll)(j-i+1)*sum[m/i]%mod+mod;
            else ans=ans-(ll)(j-i+1)*S(1,m/i)%mod+mod;
        }
        return Ans[M/m]=ans%mod;
    }
    else
    {
        if (MAP[(ll)n*mod+m]) return MAP[(ll)n*mod+m];
        ll ans=0;
        for (int i=1;i*i<=n;i++)
            if (n%i==0)
            {
                ans=ans+(ll)phi[n/i]*S(i,m/i)%mod;
                if (i*i!=n) ans=ans+(ll)phi[i]*S(n/i,m/(n/i))%mod;
            }
        return MAP[(ll)n*mod+m]=ans%mod;
    }
}
int main()
{
    ll ans=0;
    scanf("%d%d",&n,&M);
    memset(Ans,-1,sizeof Ans);
    if (n>M) swap(n,M);
    Min[1]=phi[1]=pd[1]=1;
    for (int i=2;i<N;i++)
    {
        if (!pd[i]) pri[++cnt]=Min[i]=i,phi[i]=i-1;
        for (int j=1;j<=cnt&&i*pri[j]<N;j++)
        {
            pd[i*pri[j]]=1;
            if (i%pri[j]==0)
            {
                Min[pri[j]*i]=Min[i];
                phi[i*pri[j]]=phi[i]*pri[j];
                break;
            }
            phi[i*pri[j]]=phi[i]*(pri[j]-1);
            Min[i*pri[j]]=Min[i]*pri[j];
        }
    }
    for (int i=1;i<N;i++) sum[i]=(phi[i]+sum[i-1])%mod;
    for (int i=1;i<=n;i++) ans=ans+((ll)i/Min[i]*S(Min[i],M)%mod);
    printf("%lld\n",ans%mod);
    return 0;
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值