题目链接:https://nanti.jisuanke.com/t/38226

南昌网络赛 tsy's number【莫比乌斯函数卷欧拉函数】

sum可以分块求,F(T)和T*T*T放到一起计算前缀和就可以了。

#include <bits/stdc++.h>
#define rep(i, a, b) for(int i = (a); i <= (b); i++)
#define ll long long
using namespace std;
const int N = 1e7+1000;
const int mod = 1073741824;
int sum[N];
int prime[N]; 
bool mark[N]; 
int F[N],phi[N],T[N];
int tot;
int Low[N];
void get_list(int n){
    mark[1] = 1;
    Low[1] = 1;
    phi[1] = 1;
    F[1] = phi[1];
    for(int i = 2;i <= n;i ++){
        if(!mark[i]) {
            Low[i] = i;
            prime[++tot] = i;
            phi[i] = i-1;
            F[i] = phi[i]-phi[1];                             
        }
        for(int j = 1;j<=tot&&prime[j]*i<=n;j ++){ 
            mark[i*prime[j]] = 1;
            if(!(i%prime[j])) {                    
                Low[i*prime[j]] = Low[i]*prime[j];
                if(Low[i]==i) {
                    phi[i*prime[j]] = prime[j]*phi[i];
                    F[i*prime[j]] = phi[i*prime[j]]-phi[i]; 
                }
                else {
                    phi[i*prime[j]] = phi[i/Low[i]]*phi[Low[i]*prime[j]];
                    F[i*prime[j]] = F[i/Low[i]]*F[Low[i]*prime[j]]; 
                }
                break;
            }
            Low[i*prime[j]] = prime[j];     
            phi[i*prime[j]] = phi[i]*phi[prime[j]];
            F[i*prime[j]] = F[i]*F[prime[j]];
        }
    }
    rep(i, 1, n) F[i] = 1ll*F[i]*i%mod*i%mod*i%mod;
    rep(i, 1, n) F[i] = (1ll*F[i]+F[i-1])%mod;
}
void init(int n) {
    rep(i, 1, n) {
        F[i] = (F[i-1]+1)%mod;   //第一次提交MLE了,所以只能暂时用F当sum0,phi当sum1,T当sum2
        phi[i] = (phi[i-1]+i)%mod;  //一开始的做法并没有sum,而是有sum012这三个数组
        T[i] = (T[i-1]+1ll*i*i%mod)%mod;     //后来发现空间刚好爆,少开一个数组就A了。
    }
    rep(i, 1, n) {
        sum[i] = 1ll*F[i]*phi[i]%mod*T[i]%mod;
        F[i] = 0;
        phi[i] = 0;
        T[i] = 0;
    }
}
int main() {
    //freopen("a.txt","r",stdin);
    init(1e7);
    get_list(1e7);
    int T;
    scanf("%d",&T);
    while(T--) {
        int n;
        scanf("%d",&n);
        ll ans = 0;
        for(ll l=1,r;l<=n;l=r+1) {
            r=n/(n/l);
            ans = (ans+1ll*sum[n/l]*(F[r]-F[l-1]+mod)%mod)%mod;
        }
        printf("%lld\n",ans);
    }
    //cout<<6*sizeof(sum0)/1024;
    return 0;
}

 

相关文章:

  • 2021-12-09
  • 2021-09-02
  • 2021-09-27
  • 2022-12-23
  • 2022-02-17
  • 2021-10-24
猜你喜欢
  • 2021-04-24
  • 2022-12-23
  • 2021-09-23
  • 2022-12-23
  • 2021-10-23
  • 2019-05-28
相关资源
相似解决方案