数学——费马小定理、快速幂,组合数

链接:https://www.nowcoder.com/acm/contest/114/B
来源:牛客网

求值2
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld

题目描述

Ans = 0; 
For(inti = 1; i <= n; i++) 
    For(int v = 0; v <= n; v++) 
        Ans = (Ans + C(i, v) * C(i, v)) % 998244353;
C(i,v)为组合数第i行第v列的数。
给你上面的代码中的n,请你输出Ans的值。

输入描述:

输入一个整数n

输出描述:

输出Ans的值。
示例1

输入

复制
3

输出

复制
28

备注:

n<=106

打出阶乘的表直接调用

之前用递归求阶乘直接爆栈了

然后查了一下1m递归深度最多是1024次

所以一些大数不能随便用递归

但是我们知道,所有递归都是可以用for来写的

所以就有了打表的思路(虽然说在比赛的时候没有想出来QAQ)

推出公式为 (2*n)!/(n!*n!);

数学好好玩(掉头发ing)

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+5;
const int INF = 0x3f3f3f3f;
const int mod = 998244353;
typedef long long ll;
ll A[2*maxn];
ll B[maxn];
ll power_mod(ll a,ll n){
    ll ans=1;
    while(n){
        if(n&1) ans=ans*a%mod;
        a=a*a%mod;
        n>>=1;
    }
    return ans;
}
void init(){
    A[0]=1;
    for(int i=1;i<=2e6;i++){
        A[i]=A[i-1]*i%mod;
    }
    for(int i=1;i<=1e6;i++){
        B[i]=power_mod(A[i],mod-2);
    }
}
int main(){
    init();
    int n;
    scanf("%d",&n);
    ll ans=0;
    for(int i =1 ;i<=n;i++){
        ll sum=A[2*i];
        sum=sum*B[i]%mod*B[i]%mod;
        ans=(ans+sum)%mod;
    }
    printf("%lld\n",ans);
    return 0;
}
View Code

 

posted @ 2018-06-09 15:26  buerdepepeqi  阅读(232)  评论(0编辑  收藏  举报