bzoj1485 catalan数+特殊的求组合数方法
来源:互联网 发布:禅道下载安装linux 编辑:程序博客网 时间:2024/06/07 02:09
题解
首先%%%谢大佬 感谢她给我讲了这道题O(n)求组合数的方法
以及在这里贴上谢大佬这道题的题解,因为访问量太低谢大佬都伤心了->谢大佬的良心题解你值得拥有
1、我们可以得出这道题的答案是catalan数 详解见此
2、我们会发现这道题的p是不定的并且它可以不为素数。这时我们就可以引出这种神奇的求组合数方法了——
例:求comb(m,n)%mod
大体思路:
先用线性筛筛出每个数的质数以及最小质因数
接下来求cnt[x],cnt[x]意为因数x出现的次数。最终的结果是只有cnt[prime]有值,其他都没有值。我们再for一遍素数用快速幂就可以得出结果了。
求cnt[x]的具体操作:
从大到小for(m->1) ,根据该数是在分母还是分子来确定它是+1还是-1(也就是代码中的add(x,-1)还是add(x,1))
if(当i为素数时){cnt[i]++;}
if(当i不为素数时){
cnt[i]++;
cnt[d[i]]+=cnt[i],cnt[i/d[i]]+=cnt[i];
//把cnt[i]的值转移到cnt[d[i]]和cnt[i/d[i]]
cnt[i]=0;
//最后记得清空cnt[i]因为cnt[i]已经转移到cnt[它的因数]去了
}
但是i/d[i]有可能不是素数,没关系,从大到小for,之后又会for到i/d[i],又可以继续分解它了。
最后只有素数i的cnt[i]!=0
时间复杂度分析
处理cnt[i] O(n)
for素数o(n/logn) * 快速幂O(logn)=O(n)
时间复杂度共O(n)
#include<cstdio>#include<algorithm>using namespace std;const int N=1000000+5;#define ll long longint n,p;bool noprime[2*N];int prime[N*2],d[2*N],size,cnt[2*N];void euler(){ d[1]=1; for(int i=2;i<=2*n;i++){ if(!noprime[i]){ prime[++size]=i; d[i]=i; } for(int j=1;j<=size&&i*prime[j]<=2*n;j++){ noprime[i*prime[j]]=1; d[i*prime[j]]=prime[j];//!!!! if(i%prime[j]==0) break; } }}void add(int x,int opt){ cnt[x]+=opt; if(noprime[x]){ cnt[d[x]]+=cnt[x]; cnt[x/d[x]]+=cnt[x]; cnt[x]=0; }}ll mpow(int a,int b){ ll base=a,ans=1; for(int i=b;i;i>>=1,base=(base*base)%p) if(i&1) ans=(ans*base)%p; return ans;}int main(){ scanf("%d%d",&n,&p); euler(); for(int i=2*n;i>n+1/*catalan*/;i--) add(i,1); for(int i=n;i>=1;i--) add(i,-1);//在上一波分解中如果分成了小于n的合数那么这个合数还需要被分 ll ans=1; for(int i=1;prime[i]<=2*n&&i<=size;i++) if(cnt[prime[i]]) ans=(ans*mpow(prime[i],cnt[prime[i]]))%p; printf("%lld\n",ans); return 0;}
阅读全文
0 0
- bzoj1485 catalan数+特殊的求组合数方法
- [BZOJ1485][HNOI2009]有趣的数列 catalan数
- 组合数学-catalan数
- [组合数]求组合数的几种方法总结
- [组合数]求组合数的几种方法总结
- [组合数]求组合数的几种方法总结
- 一个简单求catalan数 的程序
- bzoj1485 [HNOI2009]有趣的数列 ( 组合数 + 卡特兰数)
- 【总结】求组合数的方法
- Catalan数(组合数学)
- acm 求组合数方法
- [BZOJ1485][HNOI2009]有趣的数列(卡特兰数+组合数学)
- Catalan 数的应用
- 神奇的catalan数
- Catalan数的解法
- 神奇的Catalan数
- Catalan数的理解
- 求组合数(取模)的两种方法
- 4、替换空格 C#实现
- SpannableString打造绚丽多彩的文本显示效果
- 神奇的i++和++i
- Android源码添加自定义系统服务
- 如何通过编程赚钱?
- bzoj1485 catalan数+特殊的求组合数方法
- 订餐库系统
- java堆区详解
- java实现身份证验真
- 六种位运算
- Android购物车
- 网页注册登录数据库(一)
- python 使用正则表达式捕获文本内容并调整
- 第八周训练总结(二)