51nod 瞬间移动 (组合数学)
2017-05-02 17:19
281 查看
1627 瞬间移动 基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题 收藏 关注 有一个无限大的矩形,初始时你在左上角(即第一行第一列),每次你都可以选择一个右下方格子,并瞬移过去(如从下图中的红色格子能直接瞬移到蓝色格子),求到第n行第m列的格子有几种方案,答案对1000000007取模。 Input 单组测试数据。 两个整数n,m(2<=n,m<=100000) Output 一个整数表示答案。 Input示例 4 5 Output示例 10
试着推一下会发现他是杨辉三角, 那么就可以做了。 这里只需要求C(m-2,n-2+m-2)即可。 这里用到了Lucas定理: A、B是非负整数,p是质数。AB写成p进制:A=a a[n-1]...a[0],B=b b[n-1]...b[0]。 则组合数C(A,B)与C(a ,b )*C(a[n-1],b[n-1])*...*C(a[0],b[0]) mod p同余 即:Lucas(n,m,p)=c(n%p,m%p)*Lucas(n/p,m/p,p)
#include<iostream> #include<cstring> #include<cstdlib> #include<algorithm> #include<cctype> #include<cmath> #include<ctime> #include<string> #include<stack> #include<deque> #include<queue> #include<list> #include<set> #include<map> #include<cstdio> #include<limits.h> #define MOD 1000000007 #define fir first #define sec second #define fin freopen("/home/ostreambaba/文档/input.txt", "r", stdin) #define fout freopen("/home/ostreambaba/文档/output.txt", "w", stdout) #define mes(x, m) memset(x, m, sizeof(x)) #define Pii pair<int, int> #define Pll pair<ll, ll> #define INF 1e9+7 #define inf 0x3f3f3f3f #define Pi 4.0*atan(1.0) #define lowbit(x) (x&(-x)) #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 typedef long long ll; typedef unsigned long long ull; const double eps = 1e-9; const int mod = 1000000000+7; const int maxn = 1000; using namespace std; inline int read(){ int x=0,f=1; char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar(); return x*f; }int p = 1000000007; ll fastMod(ll n,ll m){ ll res=1; while(m){ if(m&1){ res=res*n%mod; } n=(n*n)%mod; m>>=1; } return res; } ll C(ll n,ll m){ if(n<m){ return 0; } ll ans=1; for(int i=1;i<=m;++i){ ll a=n-m+i; ll b=i; ans=ans*(a*fastMod(b,mod-2)%mod)%mod; //费马小定理求逆元 x*(p-2) mod p } return ans; } ll lucas(ll n,ll m){ if(m==0){ return 1; } return C(n%mod,m%mod)*lucas(n/mod,m/mod)%mod; //lucas定理 } int main(){ //freopen("/home/ostreambaba/文档/input.txt", "r", stdin); //freopen("/home/ostreambaba/文档/output.txt", "w", stdout); ll n,m; scanf("%lld%lld",&n,&m); ll a=m+n-4; ll b=min(m-2,n-2); printf("%lld\n",lucas(a,b)); return 0; }
相关文章推荐
- 51nod 1627 瞬间移动【组合数学】
- 51nod_1236_序列求和 V3 _组合数学
- 51nod 1667 概率好题 组合数学+容斥原理
- 51nod 1639绑鞋带(组合数学)
- 51nod 1202 子序列个数 (组合数学 +动态规划)
- 【组合数】51Nod 1627 瞬间移动
- 51nod 1667 概率好题 组合数学+容斥原理
- 51nod 1120 机器人走方格V3(组合数学+卡特兰数+Lucas)
- 【组合数学】HDU5698[瞬间移动]题解
- 51NOD 1639 绑鞋带(组合数学 + 递推)
- 51nod 1119 机器人走方格 V2【组合数学+逆元】
- 机器人走方格 V2 51Nod - 1119 组合数学+逆元
- 51nod 1670-打怪兽(组合数学)
- 51nod 序列变换 [容斥原理+莫比乌斯函数]【数论+组合数学】
- 51Nod 1119 机器人走方格 组合数学
- 51nod 1119 机器人走方格 V2 【组合数学】
- 51NOD 1509 加长棒 && Codeforces 571 A. Lengthening Sticks(组合数学 + 挡板法)
- 51nod 1122 机器人走方格 V4【组合数学】【矩阵乘法】
- 2016"百度之星" - 初赛(Astar Round2B)1003 瞬间移动 组合数学+逆元
- 51nod 1627 瞬间移动 组合数取模