P5176 公約數
$\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)\) 可以表示為:
$\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;
}