博客園同步
原題鏈接
簡要題意:
給定一個固定的 k,T 組詢問求:
i=1∑nj=1∑mgcd(i,j)k
其中 n,m,k≤5×106,T≤2×103.
沒什麼好說的,沒有部分分。根據 莫比烏斯反演性質 開始推式子!
i=1∑nj=1∑mgcd(i,j)k
=i=1∑min(n,m)dki=1∑⌊dn⌋j=1∑⌊dn⌋[gcd(i,j)==1]
=i=1∑min(n,m)dki=1∑⌊dn⌋j=1∑⌊dn⌋k∣gcd(i,j)∑μk
=i=1∑min(n,m)dkk=1∑⌊dmin(n,m)⌋⌊kdn⌋⌊kdm⌋
=i=1∑T⌊Tn⌋⌊Tm⌋d∣T∑dk×μdT
顯然 O(Tn) 的時間足以通過,前面的部分整除分塊足夠。但是對於後面這一塊較難解決,則設:
gx=d∣x∑dk×μdx
通過觀察可知這是個 積性函數。那麼顯然,對於:
x=i=1∏qpiai
存在:
gx=i=1∏qg(piai)
=i=1∏q(pik×(ai−1)×μpi+pik×ai×μ1)
=i=1∏qpik×(ai−1)×(pik−1)
首先,上面對於 g 的幾步需要解釋。那個關於 x 的式子實際上是 x 質因數分解以後的結果,pi∈prime.
然後第一步是線性篩積性函數的套路。
第二步是一個變形,考慮展開 g(piai) 的過程.
第三步就是個乘法分配律,算出 μ 而已。
好了,看看這個式子,每個部分都可以篩。結束。
時間複雜度:O(n+Tn+plogk). p 的值之後解釋。
實際得分:100pts.
#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=5e6+1;
const ll MOD=1e9+7;
inline int read(){char ch=getchar(); int f=1; while(ch<'0' || ch>'9') {if(ch=='-') f=-f; ch=getchar();}
int x=0; while(ch>='0' && ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar(); return x*f;}
inline void write(ll x) {
if(x<0) {putchar('-');write(-x);return;}
if(x<10) {putchar(char(x%10+'0'));return;}
write(x/10);putchar(char(x%10+'0'));
}
int prime[N],mu[N];
ll g[N],f[N]; bool h[N];
int T,k,cnt=0; ll ans=0;
inline ll pw(ll x,ll y) {
ll ans=1; while(y) {
if(y&1) ans=ans*x%MOD;
x=x*x%MOD; y>>=1;
} return ans;
}
inline void Euler(int n) {
f[1]=1; for(int i=2;i<=n;i++) {
if(!h[i]) prime[++cnt]=i,g[cnt]=pw(i,k),f[i]=(g[cnt]-1+MOD)%MOD;
for(int j=1;j<=cnt && i*prime[j]<=n;j++) {
h[i*prime[j]]=1;
if(i%prime[j]==0) {f[i*prime[j]]=1ll*f[i]*g[j]%MOD;break;}
f[i*prime[j]]=1ll*f[i]*f[prime[j]]%MOD;
}
}
for(int i=1;i<=n;i++) f[i]=(f[i]+f[i-1])%MOD;
}
int main() {
T=read(); k=read(); Euler(N-1);
while(T--) {
int n=read(),m=read();
ll ans=0; int r;
for(int i=1;i<=min(n,m);i=r+1) {
r=min(n/(n/i),m/(m/i));
ans=(ans+1ll*(f[r]-f[i-1]+MOD)*(n/i)%MOD*(m/i)%MOD)%MOD;
} write(ans); putchar('\n');
}
return 0;
}
顯然,你發現對於素數我們需要暴力計算 pk. 那麼,首先 5×106 以內的素數有多少個呢?代碼測試:
Link 代碼
得到結果約 3.4×105,也即 p≤3.4×105. 而 logk=log(5×106),大概是 22,不會出問題,顯然 3.4×105×22 是 107 級的,這也是程序較慢的原因(不過不影響通過,照樣 2.55s)