P5176 公約數

无敌の暗黑魔王發表於2024-08-18

P5176 公約數

\[ans=\sum _{i=1}^{m} \sum _{j=1}^{m} \sum _{k=1}^{p}gcd(ij,jk,ik)\times gcd(i,j,k)\times(\frac{gcd(i,j)}{gcd(i,k)\times gcd(j,k))}+\frac{gcd(j,k)}{gcd(i,k)\times gcd(i,j)}+\frac{gcd(i,k)}{gcd(i,j)\times gcd(j,k)} ) \]

$\quad $ 《這東西一眼就是完全不可做的🌚》,首先解決一下 \(gcd(ij,ik,jk)\) 這個東西。

先對 \(i、j、k\) 三個數進行質因數分解:

\(i=\prod _{p \in prime}{p^{a_o}}\)
\(j=\prod _{p \in prime}{p^{b_o}}\)
\(k=\prod _{p \in prime}{p^{c_o}}\)

(其實上面加不加 \(p|i\) 的條件是無所謂的,指數為 \(0\) 即可)。

那麼,\(gcd(ij,jk,ik)\) 可以表示為:

\[\prod _{p \in prime}{p^{min(a_o+b_o,b_o+c_o,a_o+c_o)}} \]

$\quad $ 可以發現,取最小值不用考慮順序問題,那我們不妨設 \(\forall p,a_o \le b_o \le c_o\)
$\quad $ 那麼 \(min(a_o+b_o,b_o+c_o,a_o+c_o)=min(a_o,b_o)+min(b_o,c_o)+min(a_o,c_o)-min(a_o,b_o,c_o)\)

$\quad $ 所以:

\begin{aligned}
gcd(ij,ik,jk)&=\prod _{p \in prime}p^{min(a_o,b_o)+min(b_o,c_o)+min(a_o,c_o)-min(a_o,b_o,c_o)}\\
&=\prod _{p\in prime}p^{min(a_o,b_o)}\prod _{p\in prime}p^{min(b_o,c_o)}\prod _{p\in prime}p^{min(a_o,c_o)}\prod _{p\in prime}p^{-min(a_o,b_o,c_o)}\\
&=\frac{gcd(i,j)gcd(j,k)gcd(i,k)}{gcd(i,j,k)}
\end{aligned}

$\quad $ 現在就可以繼續化簡答案了🌚。

\begin{aligned}
ans&=\sum _{i=1}^{m} \sum _{j=1}^{m} \sum _{k=1}^{p}gcd(ij,jk,ik)\times gcd(i,j,k)\times(\frac{gcd(i,j)}{gcd(i,k)\times gcd(j,k))}+\frac{gcd(j,k)}{gcd(i,k)\times gcd(i,j)}+\frac{gcd(i,k)}{gcd(i,j)\times gcd(j,k)} )\\
&=\sum _{i=1}^{n}\sum _{j=1}^{m}\sum _{k=1}^{p}{gcd ^2 (i,j)+gcd ^2(j,k)+gcd ^2(i,k)}\\
&=n \times \sum _{j=1}^{m}\sum _{k=1}^{p}gcd ^2(j,k)+m \times \sum _{i=1}^{n}\sum _{k=1}^{p}gcd ^2(i,k)+p \times \sum _{i=1}^{n}\sum _{j=1}^{m}gcd ^2(i,j)
\end{aligned}

$\quad $ 然後你就會發現這三個部分形式其實是一樣的,所以我們可以抽出來 \(ansl=\sum _{i=1}^{n}\sum _{j=1}^{m}{gcd ^2(i,j)}\) 單獨考慮(以下式子均認為 \(n \le m\) )。

那麼:

\begin{aligned}
ansl&=\sum _{i=1}^{n}\sum _{j=1}^{m}{gcd ^2(i,j)}\\
&=\sum _{d=1}^{n} d ^2 {\sum _{i=1}^{n}\sum _{j=1}^{m}[gcd(i,j)=d]}\\
&=\sum _{d=1}^{n}d ^2 \sum _{i=1}^{\lfloor \frac{n}{d} \rfloor}\sum _{j=1}^{\lfloor \frac{m}{d} \rfloor}[gcd(i,j)=1]\\
&=\sum _{d=1}^{n}d ^2 \sum _{i=1}^{\lfloor \frac{n}{d} \rfloor}\sum _{j=1}^{\lfloor \frac{m}{d} \rfloor}\sum _{k|d}{\mu (k)}\\
&=\sum _{d=1}^{n}d ^2 \sum _{k=1}^{\lfloor \frac{n}{d} \rfloor}\mu (k) {\lfloor \frac{n}{dk} \rfloor \lfloor \frac{m}{dk} \rfloor}
\end{aligned}
$\quad $ 仍令 \(T=dk\)

\begin{aligned}
ansl&=\sum _{T=1}^{n}{\lfloor \frac{n}{T} \rfloor \lfloor \frac{m}{T} \rfloor}\sum _{d|T}{d ^2 \mu(\frac{T}{d})}\\
\end{aligned}

$\quad $ 後半部分維護字首和即可,但是對於每個數對其倍數做貢獻的維護是 \(O(nln(n))\) 的,\(2e7\) 根本超不過去(大概是 \(3.5s\) 左右,但是會 \(T\) )。

$\quad $ 要維護的部分是兩個積性函式的積,《當然也是積性函式🌚》,考慮線性篩。

$\quad $ 令 \(h(x)=\sum _{d|x}d ^2 \mu(\frac{x}{d})\) ,當 \(x \in prime\) 的時候,計算可知 \(h(x)=x ^2 -1\) ,當兩數 \(x、y\) 互質且 \(y \in prime\) 時, \(h(xy)=h(x)h(y)\) 。《然後線性篩即可》。

$\quad $ 當然也可以用杜教篩,但是我不會🌚。

$\quad $ 再數論分塊一下,最終時間複雜度為 \(O(n+T \sqrt {n})\) 。就可以超過去了。

點選檢視程式碼
#define yhl 0
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=2e7+10,p=1e9+7;
bool vis[N];
int t,prime[N],f[N],n,m,q,tot;
void init(){
    vis[1]=1;f[1]=1;
    for(int i=2;i<N;i++){
        if(!vis[i]){
            f[i]=(1ll*i*i%p-1+p)%p;
            prime[++tot]=i;
        }
        for(int j=1;j<=tot&&i*prime[j]<N;j++){
            vis[i*prime[j]]=1;
            if(i%prime[j])f[i*prime[j]]=1ll*f[i]*f[prime[j]]%p;
            else {f[i*prime[j]]=1ll*f[i]*(1ll*prime[j]*prime[j]%p)%p;break;}
        }
    }
    for(int i=1;i<N;i++)f[i]=(f[i]+f[i-1])%p;
}
int work(int n,int m){
    if(n>m)swap(n,m);
    int ans=yhl,r=yhl;
    for(int i=1;i<=n;i=r+1){
        r=min(n/(n/i),m/(m/i));
        ans=(ans+1ll*(1ll*(n/r)*(m/r)%p)*(f[r]-f[i-1]+p)%p)%p;
    }
    return ans;
}
signed main(){
    init();
    scanf("%lld",&t);
    while(t--){
        scanf("%lld%lld%lld",&n,&m,&q);
        int ans=(1ll*q*work(n,m)%p+1ll*n*work(m,q)%p+1ll*m*work(n,q)%p)%p;
        printf("%lld\n",(ans+p)%p);
    }
    return yhl;
}

相關文章