HDU3240-Counting Binary Trees(Catalan数+求逆元(非互质))
来源:互联网 发布:个人云计算 编辑:程序博客网 时间:2024/06/05 05:03
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 of distinct non-empty binary trees of no more than n nodes, your task is to calculate T(n) mod m.
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 cases. Each case contains two integers n and m (1 <= n <= 100,000, 1 <= m <= 109) on a single line. The input ends with n = m = 0.
Output
For each test case, print T(n) mod m.
Sample Input
3 1004 100 0
Sample Output
82
Source
2009 “NIT Cup” National Invitational Contest
题意 求节点数小于n的二叉树的总和。
思路 递推公式: 设f(n)为节点数为n的二叉树的个数 f(n) = f(0)*f(n-1)+f(1)*f(n-2)+.....f(n-1)*f(0) (分成左子树和右子树)可以看出,该数列该Catalan数。
关键是还要对答案进行求模 考虑 Catalan数的递推公式 f(n) = (4*n-2)/(n+1) * f(n-1) ,有分母,因此要求逆元,但求逆元要保证两个数互质,因此可以先把m质因数分解,把分子中含有m的质因数保存起来,剩下的与m互质的直接求,分母中含有的质因数相应减去,剩下的如果大于1,那么直接求逆元,剩下的质因子就相应再乘上即可。
#include <iostream>#include <cstdio>#include <cstring>#include <vector>using namespace std;const int maxn = 100000+10;typedef long long ll;ll ans;ll cnt[maxn];vector<int> prime;int n,m;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 init(){prime.clear();memset(cnt,0,sizeof cnt);}void getPrime(){ll tmp = m;for(int i = 2; i*i <= tmp; i++){if(tmp%i==0){prime.push_back(i);while(tmp%i==0){tmp /= i;}}}if(tmp>1){prime.push_back(tmp);}}void solve(){getPrime();ans = 1;ll ret = 1;for(int i = 2; i <= n; i++){ll fz = 4*i-2,fm = i+1;for(int k = 0; k < prime.size(); k++){if(fz%prime[k]==0){while(fz%prime[k]==0){fz /= prime[k];cnt[k]++;}}}ret = (ret*fz)%m;for(int k = 0; k < prime.size(); k++){if(fm%prime[k]==0){while(fm%prime[k]==0){fm /= prime[k];cnt[k]--;}}}if(fm > 1){ret = (ret*inv(fm,m))%m;}ll tmp = ret;for(int k = 0; k < prime.size(); k++){for(int kk = 1; kk <= cnt[k]; kk++){tmp = (tmp*prime[k])%m; }}ans = (ans+tmp)%m;}printf("%I64d\n",ans);}int main(){while(~scanf("%d%d",&n,&m) && n+m){init();solve();}return 0;}
0 0
- HDU3240-Counting Binary Trees(Catalan数+求逆元(非互质))
- HDU3240 Counting Binary Trees (卡特兰数,拓欧求逆元)
- hdu3240 Counting Binary Trees 卡特兰数 乘法逆元
- uestc 1554 Counting Binary Trees (catalan 数)
- HDU 3240 Counting Binary Trees(组合数学-卡特兰数,数论-整数快速幂,数论-求逆元)
- HDOJ-3240 Counting Binary Trees(数论)
- HDU 3240 Counting Binary Trees 数论-卡特兰数
- Counting Binary Trees - HDU 3240 卡特兰数+逆元
- Leetcode 96 - Unique Binary Search Trees(dp or Catalan)
- HDU 1100 Trees Made to Order (Catalan数)
- hdu 1130 How Many Trees?(Catalan数)
- HDU 3240 Counting Binary Trees
- 扩展的欧几里得算法求逆元 hdu-3240-Counting Binary Trees
- HDU 3240 Counting Binary Trees(卡特兰数+分解素数+扩展欧拉求逆元)
- HDU 3240 Counting Binary Trees [卡特兰数] 【数论+组合数学】
- Posts Tagged 【Catalan && dfs】Unique Binary Search Trees I && II
- catalan数(poj1095)
- HDU1023(Catalan数)
- python thrift 示例<转>
- 关于/etc/hosts文件
- poj 3208 Apocalypse Someday (数位dp)
- Java异常:选择Checked Exception还是Unchecked Exception?
- Qt QDialogButtonBox 英文翻译问题
- HDU3240-Counting Binary Trees(Catalan数+求逆元(非互质))
- windows cmd命令下的最基本的压缩解压
- Android应用请求获取Root权限
- Java 覆盖私有方法
- Mac中安装MacPorts
- 【索引】AOAPC I: Beginning Algorithm Contests (Rujia Liu)
- uva11572Unique Snowflakes(滑动窗口)
- iPhone网络开发之如何使用NSURLConnection
- HDU 1269 迷宫城堡(强连通分量)