P2675 《瞿葩的数字游戏》T3-三角圣地

传送门

考虑最上面每个位置的数对答案的贡献

 

然后就很容易发现:

如果有n层,位置 i 的数对答案的贡献就是C( n-1,i ) 

然后就有很显然的贪心做法:

越大的数放越中间,这样它的贡献就会尽可能的大

然后考虑算C( i,j )

因为n很大,模数很小

所以要用lucas定理求C

C(n,m)= C(n/mo,m/mo)*C(n%mo,m%mo)

当C比较小的时候可以直接用阶乘和阶乘逆元算出

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
inline int read()
{
    int x=0,f=1; char ch=getchar();
    while(ch<'0'||ch>'9')
    {
        if(ch=='-') f=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9')
    {
        x=(x<<1)+(x<<3)+(ch^48);
        ch=getchar();
    }
    return x*f;
}
const int N=1e6+7,mo=1e4+7;
int n;
ll inv[mo],fac[mo];//注意long long
inline void pre()//预处理阶乘和阶乘逆元
{
    fac[0]=1;
    for(int i=1;i<mo;i++) fac[i]=fac[i-1]*i%mo;
    inv[0]=inv[1]=1;
    for(int i=2;i<mo;i++) inv[i]=(mo-mo/i)*inv[mo%i]%mo;
    for(int i=1;i<mo;i++) inv[i]=inv[i]*inv[i-1]%mo;//求阶乘逆元
}
inline ll C(ll x,ll y)
{
    if(x<y) return 0;
    if(x<mo&&y<mo) return fac[x]*inv[y]%mo*inv[x-y]%mo;//C较小时直接求
    return C(x%mo,y%mo)*C(x/mo,y/mo)%mo;
}
inline ll f(ll x) { return x>=mo ? x-mo : x; }//对不超过2*mo的数取模这样会快点
int main()
{
    pre();
    n=read();
    ll ans=0;
    for(int i=1;i<=n;i++)
        ans=f( ans + C(n-1,(i-1)>>1)*i%mo );
    printf("%lld",ans);
    return 0;
}

 

posted @ 2018-10-17 11:42  LLTYYC  阅读(207)  评论(0编辑  收藏  举报