FZU 1775 Counting Binary Trees 卡特兰数前n项和%m(m可为非素数

题目链接:点击打开链接

题意:

卡特兰数前n项和 结果%m

把答案当成2部分搞。

#include<stdio.h>
#include<cmath>
#define int __int64
const int N = 100000;
struct inverse_element{
    int x, y, q;
    void extend_Eulid(int a,int b)
     {
         if(b == 0){
              x = 1;y = 0;q = a;
         }else{
             extend_Eulid(b,a%b);
             int temp = x;
             x = y;
             y = temp - a/b*y;
         }
    }
    int find(int a, int b){
        extend_Eulid(a, b);
        return x;
    }
}inver;
int prime[N],primenum;//有primenum个素数 math.h
void PRIME(int Max_Prime){
	primenum=0;
	prime[primenum++]=2;
	for(int i=3;i<=Max_Prime;i+=2)
	for(int j=0;j<primenum;j++)
		if(i%prime[j]==0)break;
		else if(prime[j]>sqrt((double)i) || j==primenum-1)
		{
			prime[primenum++]=i;
			break;
		}
}
int P[N], D[N], top;
void fen(int m){
	top = 0;
	for(int i = 0; prime[i]*prime[i]<=m;i++){
		if(m%prime[i])continue;
		D[top] = 0;
		P[top++] = prime[i];
		while(m%prime[i] == 0)
			m/=prime[i];
	}
	if(m!=1){
		D[top] = 0;
		P[top++] = m;
	}
}
int n, m;
void mul(int &x, int y){
    x *= y;
    if(x >= m) x %= m;
    else if(x<0) x = x%m+m;
}
void work1(int &x, int u){
    for(int i = 0; i < top; i++)
        while(u%P[i] == 0)
            D[i]++, u/=P[i];
    mul(x, u);
}
void work2(int &x, int u){
    for(int i = 0; i < top; i++)
        while(u%P[i] == 0)
            D[i]--, u/=P[i];
    if(u!=1)
        mul(x, inver.find(u, m));
}
int Pow(int x, int y){
    int ans = 1;
    while(y){
        if(y&1)
            mul(ans, x);
        mul(x, x);
        y >>= 1;
    }
    return ans;
}
int work(){
	if(m==1)return 0;
	if(n==1)return 1;
	fen(m);
	int res = 1, sum = 1;
	for(int i = 2; i <= n; i++)
	{
        work1(res, 4*i-2);
        work2(res, i+1);
        int t = res;
        for(int i = 0; i < top; i++)
            mul(t, Pow(P[i],D[i]));
        sum = (sum+t)%m;
	}
    return sum;
}
#undef int
int main() {
	PRIME(100000);
	while(~scanf("%I64d %I64d", &n, &m)){
	    if(n+m == 0)break;
	//	n-=2;
		printf("%I64d\n", work()%m);
	}
	return 0;
}
时间: 2024-12-14 18:08:31

FZU 1775 Counting Binary Trees 卡特兰数前n项和%m(m可为非素数的相关文章

HDU 3240 Counting Binary Trees(组合数学-斯特林数,数论-整数快速幂,数论-求逆元)

Counting Binary Trees Problem Description There are 5 distinct binary trees of 3 nodes: Let T(n) be the number of distinct non-empty binary trees of no more than n nodes, your task is to calculate T(n) mod m. Input The input contains at most 10 test

HDU3240-Counting Binary Trees(Catalan数+求逆元(非互质))

Counting Binary Trees Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 564    Accepted Submission(s): 184 Problem Description There are 5 distinct binary trees of 3 nodes: Let T(n) be the number

hdu 1130How Many Trees?(卡特兰数)

卡特兰数又称卡塔兰数,英文名Catalan number,是组合数学中一个常出现在各种计数问题中出现的数列. 以比利时的数学家欧仁·查理·卡塔兰 (1814–1894)的名字来命名,其前几项为(从第零项开始) : 1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786, 208012, 742900, 2674440, 9694845, 35357670, 129644790, 477638700, 1767263190, 656412042

HNU 13101 The Triangle Division of the Convex Polygon 卡特兰数第n项%m(m可为非素数

题目链接:点击打开链接 首先要n-=2,然后就是一个卡特兰数了. 上一题用的是 h(n) = h(n-1) * (4n-2)/(n+1); 这题用的是 h(n) = (2n)! * n! / (n+1)!; 然后对阶乘分解质因数: 点击打开链接 分解完了直接快速幂. #include<stdio.h> #include<iostream> #include<cmath> #include<cstring> using namespace std; #defi

hdu1023 Train Problem II(卡特兰数)

题目意思: http://acm.hdu.edu.cn/showproblem.php?pid=1023 求出第n个卡特兰数,n<1000. 题目分析: 很明显c(n)将很大,我们可以用大数模板,也可以用java中的大整数类,这里用到了java,将java在处理大数的时候还是很有优势的. AC代码: /** * java实现卡特兰数 * 前几项:1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786,208012- * 公式 C(n)=C(2n,n

卡特兰数(Catalan)及其应用

卡特兰数 大佬博客https://blog.csdn.net/doc_sgl/article/details/8880468 卡特兰数是组合数学中一个常出现在各种计数问题中出现的数列. 卡特兰数前几项为 : C0=1,C1=1,C2=2,C3=5,C4=14,C5=42,C6=132,C7=429,C8=1430,C9=4862,C10=16796 1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786, 208012, 742900, 26

卡特兰数总结

tip: 卡特兰数是组合数学中经常出现在计数问题的数列,出栈次序是卡特兰数的一个应用. 我们将入栈视为 +1,出栈视为 -1,则限制条件为在任意位置前缀和不小于 0. 卡特兰数公式: 卡特兰数前几项为:1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786, 208012, 742900, 2674440, 9694845, 35357670, 129644790, 477638700, 1767263190, 6564120420, 244

卡特兰数通项公式在TAOCP里的推导

卡特兰数的一般项公式为: 至于怎么推导,<计算机程序设计艺术(卷一)>2.2.1节习题4的解答提到的精彩解法“反射原理”,下面是对其的概括:三国真人娱乐城 问题大意是用S表示入栈,X表示出栈,那么合法的序列有多少个(S的个数为n). 显然有c(2n, n)个含S,X各n个的序列,剩下的是计算不允许的序列数(它包含正确个数的S和X,但是违背其它条件). 在任何不允许的序列中,定出使得X的个数超过S的个数的第一个X的位置.然后在导致并包括这个X的部分序列中,以S代替所有的X并以X代表所有的S.结果

[LeetCode系列]卡特兰数(Catalan Number) 在求解独特二叉搜寻树(Unique Binary Search Tree)中的应用分析

本文原题: LeetCode. 给定 n, 求解独特二叉搜寻树 (binary search trees) 的个数. 什么是二叉搜寻树? 二叉查找树(Binary Search Tree),或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值: 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值: 它的左.右子树也分别为二叉排序树. 举个栗子,给定 n = 3, 共有 5 个. 1 3 3 2 1 \ / / / \ 3 2 1 1