一道组合数取模题
2015-10-11 11:10
330 查看
题目大意:求长度为n且每项均在[1,n]的不上升数列与不下降数列的个数和。
思路:总数就是不下降数列的个数*2-n(常数列的个数)
然后考虑不下降数列的个数
为了方便,把第0项设为0,把第n+1项设为n。
差分,然后不下降数列就是差分数组a[i]每一项大于等于0,且Σa[i]=n。
每项+1,就相当于在2n-1个空位(本来是2n+1,首尾不能放)放n个板子。
于是答案就是C(2n-1,n)*2-n
因为要取模,因为逆元可乘,所以上面和下面的阶乘都可以先乘起来再求逆元。
思路:总数就是不下降数列的个数*2-n(常数列的个数)
然后考虑不下降数列的个数
为了方便,把第0项设为0,把第n+1项设为n。
差分,然后不下降数列就是差分数组a[i]每一项大于等于0,且Σa[i]=n。
每项+1,就相当于在2n-1个空位(本来是2n+1,首尾不能放)放n个板子。
于是答案就是C(2n-1,n)*2-n
因为要取模,因为逆元可乘,所以上面和下面的阶乘都可以先乘起来再求逆元。
#include<cstdio> #include<cstring> #include<algorithm> const int mod=2000003; using namespace std; typedef long long ll; int n; ll qpow(ll a,int b){ ll res=1; for (ll j=a;b;j=j*j%mod,b>>=1) if (b&1) res=res*j%mod; return res; } void work(int n){ ll ans,A=1,B=1; for (int i=n;i<=2*n-1;i++) A=A*i%mod; for (int i=1;i<=n;i++) B=B*i%mod; for (int i=0;i<mod;i++) if (i*B%mod==A%mod){ans=i;break;} ans=((ans*2-n)%mod+mod)%mod; printf("%I64d\n",ans); } int main(){ scanf("%d",&n),work(n); return 0; }
相关文章推荐
- json使用
- Android高仿微信照片选择器+预览+显示照片
- git bash here 右键菜单失效后的修复方法
- X86在逻辑地址、线性地址、理解虚拟地址和物理地址
- jsp的el表达式使用
- mybatis04 根据用户名称模糊查询用户信息
- CentOS7上安装MySQL Workbench
- Docker 学习笔记(二)--Docker客户端和守护进程
- 八、机器学习系统设计笔记之对回归:改进的推荐
- JS实时时间显示
- The Highest Mark(01背包)
- 设置XShell快捷键 复制粘贴 并禁用智能选择
- HDU_5120 Intersection
- Swift 解决dismissViewControllerAnimated关闭当前Controller无效的问题
- 二分查找
- 七、机器学习系统设计笔记之对回归推荐
- Java对象基础的一些小问题
- SQL Delta实用案例介绍,很好的东西,帮了我不少忙
- easyui-datagrid行数据field原样输出html标签
- UVa11400