当前位置:主页 > 查看内容

计蒜客 2019 ICPC中国南昌网络邀请赛 tsy’s number(莫比乌斯反

发布时间:2021-07-18 00:00| 位朋友查看

简介:计蒜客 2019 ICPC中国南昌网络邀请赛 tsy’s number莫比乌斯反演数论分块线性筛 题目链接 https://nanti.jisuanke.com/t/38226 题目大意给定T组正整数n求 ∑ i 1 n ∑ j 1 n ∑ k 1 n φ ( i ) φ ( j 2 ) φ ( k 3 ) φ ( i ) φ ( j ) φ ( k ) φ ( g c d……

计蒜客 2019 ICPC中国南昌网络邀请赛 tsy’s number(莫比乌斯反演+数论分块+线性筛)

题目链接:https://nanti.jisuanke.com/t/38226
题目大意:给定T组正整数n,求 ∑ i = 1 n ∑ j = 1 n ∑ k = 1 n φ ( i ) φ ( j 2 ) φ ( k 3 ) φ ( i ) φ ( j ) φ ( k ) φ ( g c d ( i , j , k ) ) ? m o d ? 2 30 \sum\limits_{i=1}^{n}\sum\limits_{j=1}^{n}\sum\limits_{k=1}^{n}\frac{\varphi(i)\varphi(j^2)\varphi(k^3)}{\varphi(i)\varphi(j)\varphi(k)}\varphi(gcd(i,j,k))\space mod\space 2^{30} i=1n?j=1n?k=1n?φ(i)φ(j)φ(k)φ(i)φ(j2)φ(k3)?φ(gcd(i,j,k))?mod?230 的值。
题解:看着很唬人,其实还是有套路的。。。
原式: ∑ i = 1 n ∑ j = 1 n ∑ k = 1 n φ ( i ) φ ( j 2 ) φ ( k 3 ) φ ( i ) φ ( j ) φ ( k ) φ ( g c d ( i , j , k ) ) \sum\limits_{i=1}^{n}\sum\limits_{j=1}^{n}\sum\limits_{k=1}^{n}\frac{\varphi(i)\varphi(j^2)\varphi(k^3)}{\varphi(i)\varphi(j)\varphi(k)}\varphi(gcd(i,j,k)) i=1n?j=1n?k=1n?φ(i)φ(j)φ(k)φ(i)φ(j2)φ(k3)?φ(gcd(i,j,k))
= ∑ i = 1 n ∑ j = 1 n ∑ k = 1 n j k 2 φ ( g c d ( i , j , k ) ) =\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{n}\sum\limits_{k=1}^{n}jk^2\varphi(gcd(i,j,k)) =i=1n?j=1n?k=1n?jk2φ(gcd(i,j,k))
= ∑ i = 1 n ∑ j = 1 n ∑ k = 1 n j k 2 ∑ d = 1 n φ ( d ) [ g c d ( i , j , k ) = d ] =\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{n}\sum\limits_{k=1}^{n}jk^2\sum\limits_{d=1}^{n}\varphi(d)[gcd(i,j,k)=d] =i=1n?j=1n?k=1n?jk2d=1n?φ(d)[gcd(i,j,k)=d]
= ∑ d = 1 n φ ( d ) d 3 ∑ i = 1 ? n d ? ∑ j = 1 ? n d ? ∑ k = 1 ? n d ? j k 2 [ g c d ( i , j , k ) = 1 ] =\sum\limits_{d=1}^{n}\varphi(d)d^3\sum\limits_{i=1}^{\lfloor\frac{n}{d}\rfloor}\sum\limits_{j=1}^{\lfloor\frac{n}{d}\rfloor}\sum\limits_{k=1}^{\lfloor\frac{n}{d}\rfloor}jk^2[gcd(i,j,k)=1] =d=1n?φ(d)d3i=1?dn???j=1?dn???k=1?dn???jk2[gcd(i,j,k)=1]
= ∑ d = 1 n φ ( d ) d 3 ∑ i = 1 ? n d ? ∑ j = 1 ? n d ? ∑ k = 1 ? n d ? j k 2 ε ( g c d ( i , j , k ) ) =\sum\limits_{d=1}^{n}\varphi(d)d^3\sum\limits_{i=1}^{\lfloor\frac{n}{d}\rfloor}\sum\limits_{j=1}^{\lfloor\frac{n}{d}\rfloor}\sum\limits_{k=1}^{\lfloor\frac{n}{d}\rfloor}jk^2\varepsilon (gcd(i,j,k)) =d=1n?φ(d)d3i=1?dn???j=1?dn???k=1?dn???jk2ε(gcd(i,j,k))
= ∑ d = 1 n φ ( d ) d 3 ∑ i = 1 ? n d ? ∑ j = 1 ? n d ? ∑ k = 1 ? n d ? j k 2 ∑ t ∣ i , t ∣ j , t ∣ k μ ( t ) =\sum\limits_{d=1}^{n}\varphi(d)d^3\sum\limits_{i=1}^{\lfloor\frac{n}{d}\rfloor}\sum\limits_{j=1}^{\lfloor\frac{n}{d}\rfloor}\sum\limits_{k=1}^{\lfloor\frac{n}{d}\rfloor}jk^2\sum\limits_{t\mid i,t\mid j,t\mid k}\mu(t) =d=1n?φ(d)d3i=1?dn???j=1?dn???k=1?dn???jk2ti,tj,tk?μ(t)
= ∑ d = 1 n φ ( d ) d 3 ∑ t = 1 ? n d ? μ ( t ) t 3 ∑ i = 1 ? n d t ? ∑ j = 1 ? n d t ? ∑ k = 1 ? n d t ? j k 2 =\sum\limits_{d=1}^{n}\varphi(d)d^3\sum\limits_{t=1}^{\lfloor\frac{n}{d}\rfloor}\mu(t)t^3\sum\limits_{i=1}^{\lfloor\frac{n}{dt}\rfloor}\sum\limits_{j=1}^{\lfloor\frac{n}{dt}\rfloor}\sum\limits_{k=1}^{\lfloor\frac{n}{dt}\rfloor}jk^2 =d=1n?φ(d)d3t=1?dn???μ(t)t3i=1?dtn???j=1?dtn???k=1?dtn???jk2
f ( x ) = ∑ t = 1 x μ ( t ) t 3 ∑ i = 1 ? x t ? ∑ j = 1 ? x t ? ∑ k = 1 ? x t ? j k 2 f(x)=\sum\limits_{t=1}^{x}\mu(t)t^3\sum\limits_{i=1}^{\lfloor\frac{x}{t}\rfloor}\sum\limits_{j=1}^{\lfloor\frac{x}{t}\rfloor}\sum\limits_{k=1}^{\lfloor\frac{x}{t}\rfloor}jk^2 f(x)=t=1x?μ(t)t3i=1?tx???j=1?tx???k=1?tx???jk2 ,函数前半部分的 μ ( t ) t 3 \mu(t)t^3 μ(t)t3 可以利用前缀和数组求值,后半部分可以利用数论分块加速。那么可以令原式为函数 g ( x ) g(x) g(x) ,则有 g ( x ) = ∑ d = 1 x φ ( x ) x 3 f ( ? x d ? ) g(x)=\sum\limits_{d=1}^{x}\varphi(x)x^3f(\lfloor\frac{x}{d}\rfloor) g(x)=d=1x?φ(x)x3f(?dx??) ,同样的,这个函数的前半部分可以通过前缀和求出,后半部分也可以利用数论分块加速。
下面是AC代码。

#include<iostream>
#include<vector>
#include<algorithm>
#include<unordered_map>
using namespace std;
#define debug(x) cerr<<#x<<":"<<x<<endl
#define debug2(x,y) cerr<<#x<<":"<<x<<"  "<<#y<<":"<<y<<endl
#define debug3(x,y,z) cerr<<#x<<":"<<x<<"  "<<#y<<":"<<y<<"  "<<#z<<":"<<z<<endl
typedef long long ll;
struct fastio{
    fastio(){
        ios::sync_with_stdio(0);
        cin.tie(0);
        cout.tie(0);
    }
}fio;
const int N=1e7+5;
const int M=1<<30;
const int INV3=1789569707;
vector<int> prime,part,mu,s1,s2,phi;
void init(){
    phi=s1=s2=part=vector<int>(N,0);
    mu=vector<int>(N,-1);
    s1[1]=s2[1]=phi[1]=mu[1]=1;
    for(ll i=2;i<N;++i){
        s2[i]=((((ll)mu[i]*i*i)%M*i)%M+M+(ll)s2[i-1])%M;
        if(!part[i]){
            prime.push_back(i);
            part[i]=i;
            phi[i]=i-1;
        }
        s1[i]=((((((ll)phi[i]*i)%M)*i)%M*i)%M+(ll)s1[i-1])%M;
        for(auto j:prime){
            if(i*j>=N) break;
            part[i*j]=j;
            if(i%j==0){
                mu[i*j]=0;
                phi[i*j]=((ll)j*(ll)phi[i])%M;
                break;
            }
            else{
                mu[i*j]=-mu[i];
                phi[i*j]=((ll)phi[i]*(ll)phi[j])%M;
            }
        }
    }
}
unordered_map<int,int> f_v;
ll f(ll x){
    if(f_v[x]) return f_v[x];
    ll res=0;
    for(ll l=1,r;l<=x;l=r+1){
        r=x/(x/l);
        ll y=((ll)(1+x/l)*(x/l)>>1ll)%M;
        res=(res+((s2[r]-s2[l-1])%M*((ll)(x/l)*y%M*y%M*(((ll)(x/l)<<1ll)+1)%M*INV3%M)+M)%M)%M;
    }
    return f_v[x]=res;
}
int g(ll x){
    int res=0;
    for(ll l=1,r;l<=x;l=r+1){
        r=x/(x/l);
        res=((res+(ll)(s1[r]-s1[l-1])%M*f(x/l)%M)%M+M)%M;
    }
    return res;
}
signed main(){
    int t,n;
    cin>>t;
    init();
    while(t--){
        cin>>n;
        cout<<g(n)<<endl;
    }
}

要注意的是,我们可以利用map对 f ( x ) f(x) f(x) 的值进行储存,避免不必要的计算(如果不用map会TLE的说)。同时结果要返回正整数值,否则会WA。

(勉勉强强卡过了吧。。。)

;原文链接:https://blog.csdn.net/m0_52639539/article/details/115760344
本站部分内容转载于网络,版权归原作者所有,转载之目的在于传播更多优秀技术内容,如有侵权请联系QQ/微信:153890879删除,谢谢!

推荐图文


随机推荐