【BZOJ 2721】

在這裏插入圖片描述


通分:
xyx+y=n!\frac{xy}{x+y}=n!
移項並打開括號:
xy=n!x+n!yxy=n!x+n!y
合併同類項:
(yn!)x=n!yx=n!yyn!(y-n!)x=n!y \quad \Longrightarrow \quad x=\frac{n!y}{y-n!}
t=yn!t=y-n!,則y=t+n!y=t+n!。所以:
x=n!(t+n!)t=y+(n!)2tx=\frac{n!(t+n!)}{t}=y+\frac{(n!)^2}{t}
因爲xx是一個整數,所以t(n!)2t|(n!)^2。於是我們把原問題轉化爲求m=(n!)2m=(n!)^2的因數個數。
我們將mm分解質因數:
m=i=1kpiaim=\prod_{i=1}^k p_i^{a_i}
那麼由乘法原理,m的因數個數爲:
ans=i=1k(ai+1)ans=\prod_{i=1}^k(a_i+1)
實現時,我們可以把1 n1~n分解質因數。枚舉i[1,n]i\in [1,n],維護前綴積即可。

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int mn = 1000005, mod = 1e9 + 7;
int pri[mn], cnt; bool vis[mn];
ll ans = 1, num[mn];
int main()
{
    int n;
    scanf("%d", &n);
    vis[1] = 1;
    for(int i = 2; i <= n; i++)
    {
        if(!vis[i]) pri[++cnt] = i;
        for(int j = 1; j <= cnt && pri[j] * i <= n; j++)
        {
            vis[pri[j] * i] = 1;
            if(i % pri[j] == 0) break;
        }
    }
    //一點技巧
    for(int i = 1; i <= cnt; i++)
        for(int j = pri[i]; j <= n; j += pri[i])
            for(int t = j; t % pri[i] == 0; t /= pri[i]) ++num[i];
    for(int i = 1; i <= cnt; i++)
        (ans *= (num[i] << 1) | 1) %= mod;
    printf("%lld\n", ans);
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章