0
点赞
收藏
分享

微信扫一扫

[呱一题] 爷奖国方程(数论)

small_Sun 2022-04-27 阅读 10

@[TOC]([呱一题] 爷奖国方程(数论))

原题

题解

我们不妨设 K = T ! K=T! K=T!,那么有:

1 1 N + 1 M = K ⇔ 1 N + 1 M = 1 K ⇔ ( N + M ) K = N M ⇔ − ( N + M ) K + N M = 0 ⇔ K 2 − ( N + M ) K + N M = K 2 ⇔ ( N − K ) ( M − K ) = K 2 \frac{1}{\frac{1}{N}+\frac{1}{M}}=K\\ \\ \Leftrightarrow \frac{1}{N}+\frac{1}{M}=\frac{1}{K}\\ \\ \Leftrightarrow (N+M)K=NM\\ \\ \Leftrightarrow -(N+M)K+NM=0\\ \\ \Leftrightarrow K^2-(N+M)K+NM=K^2\\ \\ \Leftrightarrow (N-K)(M-K)=K^2\\ N1+M11=KN1+M1=K1(N+M)K=NM(N+M)K+NM=0K2(N+M)K+NM=K2(NK)(MK)=K2

显然, ( N − K ) , ( M − K ) (N-K),(M-K) (NK),(MK) K 2 K^2 K2的两个因子,所以答案即为 K 2 K^2 K2的因子个数,即 ( T ! ) 2 {(T!)}^2 (T!)2的因子个数。

我们对 T ! T! T!做质因子分解,有:

T ! = p 1 k 1 ⋅ p 2 k 2 ⋯ p n k n ( T ! ) 2 = p 1 2 k 1 ⋅ p 2 2 k 2 ⋯ p n 2 k n T!=p_1^{k_1} \cdot p_2^{k_2} \cdots p_n^{k_n}\\ (T!)^2=p_1^{2k_1} \cdot p_2^{2k_2} \cdots p_n^{2k_n}\\ T!=p1k1p2k2pnkn(T!)2=p12k1p22k2pn2kn

那么 ( T ! ) 2 (T!)^2 (T!)2的因子个数为:

a n s w e r = ( 2 k 1 + 1 ) ⋅ ( 2 k 1 + 1 ) ⋯ ( 2 k n + 1 ) answer=(2k_1+1) \cdot (2k_1+1) \cdots (2k_n+1)\\ answer=(2k1+1)(2k1+1)(2kn+1)

现在我们考虑如何对 T ! T! T!做质因子分解,对于一个质数 X X X,在 [ 1 , T ] [1,T] [1,T]中,有 ⌊ T X ⌋ \lfloor \frac{T}{X} \rfloor XT个数含有至少1个这个质因子,有 ⌊ T X 2 ⌋ \lfloor \frac{T}{X^2} \rfloor X2T个数含有至少2个这个质因子……

所以我们只需要先筛出T以内的质数,再对每个质数做上述处理计算T!中含有多少个这个质因子即可。

代码实现

首先,我们要筛出所有的质数,这里用线性筛法。

const int N=1e7+1;
const int M=19260817;

vector<int> prime;
bool notPrime[N];

void filte()
{
    for(int i=2;i<N;i++)
    {
        if(!notPrime[i])
        {
            //cout<<i<<endl;
            prime.push_back(i);
            for(long long j=1ll*i*i;j<N;j+=i)
            {
                notPrime[j]=true;
            }
        }
    }
}

然后,我们对每个质数计算 T ! T! T!包含多少个因子。

long long LTZ_euqition(long long T)
{
    long long answer=1;
    int cnt=0;
    for(int X:prime)
    {
        if(X>T)break;
        long long x=X;
        while(x<=T)
        {
            cnt+=T/x;
            x*=X;
        }
        answer*=(2*cnt+1);
        answer%=M;
        cnt=0;
    }
    return answer;
}

下附完整实现

// by Concyclics
//
//
#include <iostream>
#include <vector>
using namespace std;

const int N=1e7+1;
const int M=19260817;

vector<int> prime;
bool notPrime[N];

void filte()
{
    for(int i=2;i<N;i++)
    {
        if(!notPrime[i])
        {
            //cout<<i<<endl;
            prime.push_back(i);
            for(long long j=1ll*i*i;j<N;j+=i)
            {
                notPrime[j]=true;
            }
        }
    }
}

long long LTZ_euqition(long long T)
{
    long long answer=1;
    int cnt=0;
    for(int X:prime)
    {
        if(X>T)break;
        long long x=X;
        while(x<=T)
        {
            cnt+=T/x;
            x*=X;
        }
        
        answer*=(2*cnt+1);
        answer%=M;
        cnt=0;
    }
    return answer;
}

int main()
{
    
    filte();
    int T;
    cin>>T;
    cout<<LTZ_euqition(T);
}

举报

相关推荐

0 条评论