簡要題意:
求
其中 表示 的因數個數。
一言不合就推式子!
算法一
我會暴力!
時間複雜度:. 實際得分:.
恭喜你,一長串式子白推了
算法二
推式子基本結束了,你會發現,式子長得可怕,這並不是我們 題的前兆!比方說 二元弱化版 本人也寫了 題解,可是弱化版推的最後式子很簡單啊!
所以首先我們分析,如果就這個式子枚舉, 是跑不掉的。因爲我們沒有消掉一個 ,反而按照 所謂的莫比烏斯反演套路 增加了 .
令
將原式後面的一長串簡化:
這只是看起來簡單了,實質上, 預處理 可以辦到,但是就當前式子,大力枚舉還是 ,沒有一點部分分可拿。這是令人痛苦的地方。
時間複雜度:. 實際得分:.
算法三
越接近答案的推導,就顯得越困難。現在我們到了黎明前那個最黑暗的時刻。
我們考慮,什麼時候 對答案沒有貢獻。
顯然, 或 或 都會沒有貢獻。
而 ,就需要 或 或 .
似乎情況還蠻多的?
所以我們考慮感性一點,枚舉 ,然後 合法 當且僅當 .
對於合法的 連邊,我們就得到了一張圖。
那麼合法的情況是怎樣的?即 在原圖中同時存在。
即需要求出原圖的 三元環個數,可以參考 不常用的黑科技——「三元環」,在 的時間求解。
那麼,,也就是這個圖的邊數會不會很大呢?
一位叫做 的人告訴我們邊數最多隻有 條,所以就放心吧!
對於後面的一堆東西用 整除分塊 可以實現。
對於 ,用 整除分塊 需要格外小心,常數很危險,需要反覆卡常才能過
本人在卡常 次後 了本題。。 把幾乎同樣的代碼不斷提交
時間複雜度:.
其中 .
期望得分:. 實際得分: ~ .(取決於常數)
如果你交我代碼發現A不了,只能說你人品差了
// i=-~i 是 i++ 的優化
// 所有 min , max , gcd 手寫卡常
// register 寄存器用來優化
// 一段 GCC 優化模板
#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(5000)
#pragma GCC optimize(100000000)
#pragma GCC optimize("Ofast")
#pragma GCC optimize("inline")
#pragma GCC optimize("-fgcse")
#pragma GCC optimize("-fgcse-lm")
#pragma GCC optimize("-fipa-sra")
#pragma GCC optimize("-ftree-pre")
#pragma GCC optimize("-ftree-vrp")
#pragma GCC optimize("-fpeephole2")
#pragma GCC optimize("-ffast-math")
#pragma GCC optimize("-fsched-spec")
#pragma GCC optimize("unroll-loops")
#pragma GCC optimize("-falign-jumps")
#pragma GCC optimize("-falign-loops")
#pragma GCC optimize("-falign-labels")
#pragma GCC optimize("-fdevirtualize")
#pragma GCC optimize("-fcaller-saves")
#pragma GCC optimize("-fcrossjumping")
#pragma GCC optimize("-fthread-jumps")
#pragma GCC optimize("-funroll-loops")
#pragma GCC optimize("-fwhole-program")
#pragma GCC optimize("-freorder-blocks")
#pragma GCC optimize("-fschedule-insns")
#pragma GCC optimize("inline-functions")
#pragma GCC optimize("-ftree-tail-merge")
#pragma GCC optimize("-fschedule-insns2")
#pragma GCC optimize("-fstrict-aliasing")
#pragma GCC optimize("-fstrict-overflow")
#pragma GCC optimize("-falign-functions")
#pragma GCC optimize("-fcse-skip-blocks")
#pragma GCC optimize("-fcse-follow-jumps")
#pragma GCC optimize("-fsched-interblock")
#pragma GCC optimize("-fpartial-inlining")
#pragma GCC optimize("no-stack-protector")
#pragma GCC optimize("-freorder-functions")
#pragma GCC optimize("-findirect-inlining")
#pragma GCC optimize("-fhoist-adjacent-loads")
#pragma GCC optimize("-frerun-cse-after-loop")
#pragma GCC optimize("inline-small-functions")
#pragma GCC optimize("-finline-small-functions")
#pragma GCC optimize("-ftree-switch-conversion")
#pragma GCC optimize("-foptimize-sibling-calls")
#pragma GCC optimize("-fexpensive-optimizations")
#pragma GCC optimize("-funsafe-loop-optimizations")
#pragma GCC optimize("inline-functions-called-once")
#pragma GCC optimize("-fdelete-null-pointer-checks")
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N=8e5+5,MOD=1e9+7;
inline ll read(){char ch=getchar(); ll f=1;while(ch<'0' || ch>'9') {if(ch=='-') f=-f; ch=getchar();}
ll x=0;while(ch>='0' && ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();return x*f;}
ll a,b,c,T,cnt,tot,ans;
ll lst[N],d[N],p[N],mu[N],ok[N],ord[N],deg[N],f[N],from[N],to[N],lcm[N],mrk[N];
vector<ll>v[N],w[N];
inline ll min(ll a,ll b){return a<b?a:b;}
inline ll max(ll a,ll b){return a>b?a:b;}
inline ll gcd(ll a,ll b){return (!b)?a:gcd(b,a%b);}
int main() {
p[1]=mu[1]=1;
for(register int i=2;i<N;i=-~i) {
if(!p[i]) lst[++cnt]=i,mu[i]=-1;
for(register int j=1;j<=cnt;j=-~j){
if(i*lst[j]>=N) break;
p[i*lst[j]]=1;
if(i%lst[j]==0) {mu[i*lst[j]]=0;break;}
mu[i*lst[j]]=-mu[i];
}
} for(register int i=1;i<N;i=-~i)
if(mu[i]) ok[++tot]=i,ord[i]=tot;
for(register int i=1;i<N;i=-~i) {
for(register int j=1;i*j<N;j=-~j) d[i*j]++;
f[i]=(f[i-1]+d[i])%MOD;
} T=read();
while(T--) {
memset(deg,0,sizeof(deg));
memset(v,0,sizeof(v));
memset(w,0,sizeof(w));
a=read(),b=read(),c=read();
ll mn=min(min(a,b),c),mx=max(max(a,b),c);
ll e=ans=0;
for(register int i=1;i<=tot;i=-~i){
if(ok[i]>mx) break;
for(register int j=1;j<=tot;j=-~j){
if(ok[i]*ok[j]>mx) break;
if(!mu[ok[i]*ok[j]]) continue;
for(register int k=j+1;k<=tot;k=-~k){
if(ok[i]*ok[j]*ok[k]>mx) break;
if(mu[ok[i]*ok[k]]==0||gcd(ok[j],ok[k])>1) continue;
from[++e]=ord[ok[i]*ok[j]],to[e]=ord[ok[i]*ok[k]],lcm[e]=ok[i]*ok[j]*ok[k];
deg[from[e]]++,deg[to[e]]++;
}
}
}
for(register int i=1;i<=tot;i=-~i) {
if(ok[i]>mn) break;
ans+=mu[ok[i]]*mu[ok[i]]*mu[ok[i]]*f[a/ok[i]]*f[b/ok[i]]*f[c/ok[i]];
}
for(register int i=1;i<=e;i=-~i) {
v[from[i]].push_back(to[i]),w[from[i]].push_back(lcm[i]);
v[to[i]].push_back(from[i]),w[to[i]].push_back(lcm[i]);
}
for(register int i=1;i<=tot;i=-~i) {
if(ok[i]>min(a,b)) break;
for(register int j=0;j<v[i].size();j=-~j) {
ll x=ok[i],y=ok[v[i][j]],z=w[i][j];
ans=(ans+mu[x]*mu[y]*mu[y]*f[a/z]*f[b/z]*f[c/y]);
ans=(ans+mu[x]*mu[x]*mu[y]*f[a/x]*f[b/z]*f[c/z]);
ans=(ans+mu[x]*mu[x]*mu[y]*f[a/z]*f[b/x]*f[c/z]);
}
} ans=(ans+MOD)%MOD;
memset(v,0,sizeof(v));
memset(w,0,sizeof(w));
for(register int i=1;i<=e;i=-~i) {
if(deg[from[i]]>=deg[to[i]]) v[from[i]].push_back(to[i]),w[from[i]].push_back(lcm[i]);
else v[to[i]].push_back(from[i]),w[to[i]].push_back(lcm[i]);
}
for(register int i=1;i<=tot;i=-~i) {
if(ok[i]>mx) break;
for(register int j=0;j<v[i].size();j=-~j) mrk[v[i][j]]=w[i][j];
for(register int j=0;j<v[i].size();j=-~j){
ll x=v[i][j];
for(register int k=0;k<v[x].size();k=-~k){
ll y=v[x][k],p=mrk[y],q=w[i][j],r=w[x][k];
if(!mrk[y]) continue;
ll st1,st2,st3,st4,st5,st6;
st1=f[a/p]*f[b/q]*f[c/r];
st2=f[a/p]*f[b/r]*f[c/q];
st3=f[a/q]*f[b/p]*f[c/r];
st4=f[a/q]*f[b/r]*f[c/p];
st5=f[a/r]*f[b/p]*f[c/q];
st6=f[a/r]*f[b/q]*f[c/p];
ans=(ans+mu[ok[i]]*mu[ok[x]]*mu[ok[y]]*(st1+st2+st3+st4+st5+st6)+MOD)%MOD;
}
} for(register int j=0;j<v[i].size();j=-~j) mrk[v[i][j]]=0;
}
printf("%lld\n",(ans+MOD)%MOD);
}
return 0;
}