HDU-3240 (number + Cattleya after inversing prime factor decomposition)

Cattleya number of related equations:

  1. \(H_n = {C_{2n}^n \over n+1)}\)
  2. \(H_n = {(4n-2)\over n+1}\times H_{n-1}\)
  3. \ (H_n = C_ {2n} ^ n - C_ {2n} ^ {n-1} \)
  4. $ H_n = \begin{cases} \sum_{i=1}^{n} H_{i-1} H_{n-i} & n \geq 2, n \in \mathbf{N_{+}}\ 1 & n = 0, 1 \end{cases} $

Since \ (the n-\ Le 100000 \) , it is not considered a fourth, first and third requirements for various number combinations may not use recursion to find, and then use a formula to be calculated in advance because of the inverse factorial and factorial in this question is no guarantee that the m is a prime number, it is not easy to calculate.

For the third, and it was calculated assuming \ (H_ {n-1} \) then only requires a \ ({4n-2 \ over n + 1} \) to

First prime factor decomposition of m, then the molecular \ (4N-2 \) , obtains all indices m prime factors after decomposition, and then to the denominator \ (n-+. 1 \) , is also determined prime factor decomposition m All indices, two array indices before and after the subtraction. The remaining numerator and denominator and m coprime portion can directly request retained in the pre recursive answer.

In summary, the current recursive common answer is recorded by a pre and a variable array index, so the answer to the ground after the introduction of the current time to accumulate, but also with pre multiplying all prime factors

#include <bits/stdc++.h>
using namespace std;
const int N = 1000010;
typedef long long ll;
int n,m;
int cnt[N];
vector<ll> v;
void exgcd(ll a,ll b,ll& d,ll& x,ll& y) {
    if(!b) {
        d = a; x = 1; y = 0;
    }else{
        exgcd(b,a%b,d,y,x); y -= x*(a/b);
    }
}
ll inv(ll a,ll n){
    ll d,x,y;
    exgcd(a,n,d,x,y);
    return d== 1?(x+n)%n:-1;
}
void getPrime(int x){
    for(int i=2;i*i<=x;i++){
        if(x % i)continue;
        while(x%i==0)x/=i;
        v.push_back(i);
    }
    if(x > 1)v.push_back(x);
    return;
}
int main(){
    while(cin >> n >> m){
        if(n == 0 && m == 0)break;
        v.clear();
        memset(cnt,0,sizeof cnt);
        ll res = 1 % m;
        ll pre = 1;
        getPrime(m);//对m进行分解质因数
        for(int i=2;i<=n;i++){
            ll fz = 4 * i - 2, fm = i + 1;
            for(int j=0;j<v.size();j++){
                if(fz % v[j] == 0)
                while(fz % v[j] == 0){
                    fz /= v[j];
                    cnt[j] ++;//指数++
                }
            }
            pre = pre * fz % m;//剩余互质部分直接乘
            for(int j=0;j<v.size();j++){
                if(fm%v[j] == 0)
                while(fm % v[j] == 0){
                    fm /= v[j];
                    cnt[j] --;//指数--
                }
            }
            if(fm > 1) pre = pre * inv(fm,m) % m;//更新pre
            ll tmp = pre;
            for(int j=0;j<v.size();j++){
                for(int k=1;k<=cnt[j];k++){
                    tmp = (tmp * v[j]) % m;//计算当前答案
                }
            }
            res = (res + tmp) % m;
        }
        cout << res << endl;
    }
    return 0;
}

Why not always directly to the prime factors calculated directly into the pre in it, because after the calculation, the denominator (n + 1) be the decomposition of the quality factor, the situation is not likely to reduce the appearance, so we have to always use an array of records this section has a common factor and a portion m

Guess you like

Origin www.cnblogs.com/1625--H/p/11462589.html