[莫比乌斯反演] 51nod1584. 加权约数和

杜教筛学傻了…一道反演题…我竟然差点推成杜教筛??

A(n)=i=1nσ(in)

这个东西推一下就变成

t|nμ(t)tf(nt)g(nt)

f(n)=d|nd,g(n)=i=1nf(n)

这个可 O(nlnn)

那么答案就是

2i=1niA(i)i=1niσ(i2)

预处理后 O(1) 输出就好了

最后还被卡常啊……
最后能线性筛的东西全改成线性筛才过……

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <ctime>

using namespace std;

typedef long long ll;

const int N=1000010,P=1e9+7;

int p[N],mu[N],f[N],g[N],h[N],ans[N],fac[N],w[N];

inline void Pre(const int n){
  mu[1]=1; f[1]=1;
  for(int i=2;i<=n;i++){
    if(!p[i])
      p[++*p]=i,mu[i]=-1,fac[i]=i,w[i]=(1LL*i*i+i+1)%P,f[i]=i+1;
    for(int j=1;j<=*p && 1LL*i*p[j]<=n;j++){
      p[i*p[j]]=1;
      if(i%p[j]){
    mu[i*p[j]]=-mu[i];
    fac[i*p[j]]=p[j];
    w[i*p[j]]=1LL*w[i]*w[p[j]]%P;
    f[i*p[j]]=1LL*f[i]*f[p[j]]%P;
      }
      else{
    fac[i*p[j]]=fac[i]*p[j];
    if(fac[i]==i){
      fac[i*p[j]]=fac[i]*p[j];
      w[i*p[j]]=(w[i]+1LL*fac[i]*fac[i]%P*p[j]+1LL*fac[i]*fac[i]%P*p[j]%P*p[j])%P;
      f[i*p[j]]=(f[i]+fac[i]*p[j])%P;
    }
    else{
      fac[i*p[j]]=fac[i]*p[j];
      w[i*p[j]]=1LL*w[i/fac[i]]*w[p[j]*fac[i]]%P;
      f[i*p[j]]=1LL*f[i/fac[i]]*f[p[j]*fac[i]]%P;
    }
    break;
      }
    }
  }
  for(int i=1;i<=n;i++) g[i]=(g[i-1]+f[i])%P;
  for(int i=1;i<=n;i++)
    for(int j=i;j<=n;j+=i)
      h[j]=(h[j]+1LL*mu[i]*i*f[j/i]%P*g[j/i])%P;
  for(int i=1;i<=n;i++)
    ans[i]=(ans[i-1]+1LL*i*h[i])%P;
  w[1]=1;
  for(int i=1;i<=n;i++) w[i]=(1LL*i*w[i]+w[i-1])%P;
  for(int i=1;i<=n;i++)
    ans[i]=(2LL*ans[i]-w[i])%P,ans[i]=(ans[i]+P)%P;
}

int main(){
  freopen("1.in","r",stdin);
  freopen("1.out","w",stdout);
  int t,n; scanf("%d",&t); Pre(1000000);
  for(int i=1;i<=t;i++)
    scanf("%d",&n),printf("Case #%d: %d\n",i,ans[n]);
  return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值