码迷,mamicode.com
首页 > 其他好文 > 详细

bzoj1485: [HNOI2009]有趣的数列

时间:2016-07-04 01:13:42      阅读:211      评论:0      收藏:0      [点我收藏+]

标签:

卡特兰数。

这道题打下表可以看出前几项是卡特兰数(怎么想到打表和卡特兰数?我事先看了题解,为了确认一下。)

因为p不是质数,所以不能用乘法逆元。

我们可以把C(2*n,n)/(n+1)的每一项分解成一个质数,然后乘,这样就可以了。

#include<cstdio>
#include<algorithm>
#include<cstring>
#define LL long long 
using namespace std;
const int maxn = 2000000 + 10;
int prime[maxn],m[maxn],s[maxn];
bool mark[maxn];
int n,cnt,mod;
LL res=1;

void getpri() {
    for(int i=2;i<=2*n;i++) {
        if(!mark[i]) {prime[++cnt]=i; m[i]=cnt;}
        for(int j=1;j<=cnt;j++) {
            if(prime[j]*i>2*n) break;
            mark[prime[j]*i]=1; m[prime[j]*i]=j;
            if(i%prime[j]==0) break;
        }
    }
}

void add(int x,int f) {
    while(x!=1) {
        s[m[x]]+=f;
        x/=prime[m[x]];
    }
}


int main() {
    scanf("%d%d",&n,&mod);
    getpri();
    for(int i=n+2;i<=2*n;i++) add(i,1);
    for(int i=1;i<=n;i++) add(i,-1);
    for(int i=1;i<=cnt;i++) 
        while(s[i]--) res=(res*prime[i])%mod;
    printf("%lld\n",res);    
    return 0;    
}

bzoj1485: [HNOI2009]有趣的数列

标签:

原文地址:http://www.cnblogs.com/invoid/p/5639159.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!