HDU 3398 String 组合数学+N!质因数分解 卡特兰数
来源:互联网 发布:ipad淘宝发布宝贝 编辑:程序博客网 时间:2024/04/28 03:02
String
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2305 Accepted Submission(s): 668
Problem Description
Recently, lxhgww received a task : to generate strings contain '0's and '1's only, in which '0' appears exactly m times, '1' appears exactly n times. Also, any prefix string of it must satisfy the situation that the number of 1's can not be smaller than the number of 0's . But he can't calculate the number of satisfied strings. Can you help him?
Input
T(T<=100) in the first line is the case number.
Each case contains two numbers n and m( 1 <= m <= n <= 1000000 ).
Each case contains two numbers n and m( 1 <= m <= n <= 1000000 ).
Output
Output the number of satisfied strings % 20100501.
Sample Input
12 2
Sample Output
2
/*HDOJ 3398 组合数学+N!质因数分解汗!不会。卡特兰数 1大于0的个数 ①:我们设初始在坐标系的原点(0,0),从字符串第一位开始,碰到一个1就向上走,碰到一个0就向右走,那么由n个1、m个0组成的字符串最后必定走到(n,m)点,即满足由n个1、m个0组成的字符串的个数为C(n+m,n)=C(n+m,m) (满足n+m长度内n个长度走1或者m个长度走0)。②:对于任意前缀中1的个数不少于0的个数的字符串的个数这个条件,可以看成是坐标系中,从(0,0)点走到(m, n)点,并且跟y=x-1这条直线不相交的方案数。又因为(0,0)点关于直线y=x-1的对称点是(1,-1),而从(1,-1)点走到(m, n)点的所有方案一定都会与直线y=x-1相交,对于这些方案,将从(1,-1)点到与y=x-1的第一个交点之间的路径关于y=x-1对称翻转过去,就可以得到所有不满足题意的从(0,0)点走到(m, n)点的方案,C(n+m,m-1)=C(n+m,n+1) 为什么n+1 于是最终答案就是C(n+m, n)-C(n+m,n+1)。 接下来就是求上式子模20100501的值,因为n、m很大,所以我们利用质因数分解来分解阶乘,然后分子分母抵消指数最后求指数幂的和即可,但是这样做还是会TLE。而用对于阶乘,有很多非常好的性质可以利用(不利用就TLE。。。),下面介绍N!的质因数分解,也就是求N!中x的幂,首先因为N! = 1*2*3*……*N,所以N!中x的幂就是各个数质因数分解后x的幂之和,考虑含1,2,……,N中含x^1的共有x^1,2*x^1,……,y*x^1共y个,其中y=floor(N/x^1),而含x^2的共有x^2,2*x^2,……,y*x^2共y个,其中y=floor(N/x^2)=floor((N/x)/x),所以可以利用递归来计算N!中x的幂C(n+m, n)-C(n+m,n+1)=(n+m)!/(n+m-1)!n!-(n+m)!/(n+m-1)!(n+1)!=(n+1-m)(n+m)!/(n+1)!m!power定理分解素数,对于每个素数分别算幂,取模相乘即可。*/#include<iostream>#include<stdio.h>#include<algorithm> using namespace std;#define N 1000001typedef __int64 LL;int f[N*2+1],prime[N*2+1],k;/*8!/28/2=4 4/2=2 2/2=1第1轮 2 4 6 8 含有2的 4第2轮 1 2 3 4 含有2的 2第3轮 1 2 含有2的 1数字:2 4 6 8 1 2 1 3=7*/int cal(int p,int n)//计算n!是素数p的幂次 {int ans=0;while(n){n/=p;ans+=n;}return ans;} void calPrime(){ memset(f,0,sizeof(f)); k=0; for(int i=2;i<=N*2;i++){ if(f[i])continue;prime[k++]=i; for(int j=i*2;j<=N*2;j+=i)f[j]=1; } } int main(){ int t,n,m,i; calPrime(); scanf("%d",&t); while(t--){ scanf("%d%d",&n,&m); LL ans=1;int nm=n-m+1; for(i=0;i<k&&prime[i]<=n+m;i++){ int cnt=0; while(nm%prime[i]==0)//计算n-m+1的素数的幂 {nm/=prime[i];cnt++; } //计算整个公式的素数的幂 int ipow=cnt+cal(prime[i],n+m)-cal(prime[i],n+1)-cal(prime[i],m); for(int j=1;j<=ipow;j++){ ans=(ans*prime[i])%20100501; } } printf("%I64d\n",ans); } return 0; }
0 0
- HDU 3398 String 组合数学+N!质因数分解 卡特兰数
- 【组合数学】卡特兰数
- 组合数学:卡特兰数
- 组合数学--卡特兰数
- hdu 3240 卡特兰数+质因数分解+扩展欧几里得求乘法逆元
- hdu2067 组合数学 卡特兰数
- 组合数学之卡特兰数
- 组合数学——卡特兰数
- 【组合数学】卡特兰数总结
- 组合数学 组合数 卡特兰数 斯特林数
- [HDU 5184][BestCoder #32]Brackets(卡特兰数+组合数学+乘法逆元)
- hdu 1133 Buy the Ticket(卡特兰数变形+组合数学+java大数)
- HDU 3240 Counting Binary Trees [卡特兰数] 【数论+组合数学】
- 【HDU】1131 - Count the Trees(组合数学 - 卡特兰数 & java)
- HDU 2067 小兔的棋盘 (组合数学 卡特兰数)
- 读书笔记之组合数学——卡特兰数
- Move · 卡特兰数 + 组合数学 附逆元
- [组合数学 卡特兰数] BZOJ 1856 [Scoi2010]字符串
- HDU 1028 Ignatius and the Princess III 母函数
- Android开发系列(十七):读取assets目录下的数据库文件
- VC++的工程文件
- 2014ACM/ICPC亚洲区域赛牡丹江站现场赛-D ( ZOJ 3822 ) Domonation
- UVaOJ 1368 - DNA Consensus String
- HDU 3398 String 组合数学+N!质因数分解 卡特兰数
- ADB源码分析(二)——adb sever的启动
- 树状数组的区间修改,单点查询
- Linux中telnet的安装与配置
- Whac-a-Mole(动态规划)
- HDU 3571 N-dimensional Sphere 高斯消元法
- 开山第一篇笔记+教程(发给热爱ROS的童鞋)——ROS下读取摄像头图像 图像转换
- Intel Galileo——开机
- 把JSP放到WEB-INF后以保护JSP源代码