A Monotonic Matrix(详解)

A Monotonic Matrix
感谢楼下指正@Ruger


先备知识

LGV 算法 (Lindström–Gessel–Viennot lemma)

图片说明
求以上矩阵的行列式,其中 e(a,b) 是从a到b的方法数,带入求行列式即可得到(a1,a2,...an) 到 (b1,b2,...bn) 的所有不相交路径的种数

思路

考虑01和12的分界线
是(n, 0)到(0,m)的两条不相交(可重合)路径
分界线以及分界线以上的点是一种,分界线下是一种
平移其中一条变成(n-1, -1)到(-1,m-1);
变成


然后进行预处理打表前2*n的阶乘和阶乘逆元就行了


#include <bits/stdc++.h>
#define mem(ar,num) memset(ar,num,sizeof(ar))
#define me(ar) memset(ar,0,sizeof(ar))
#define lowbit(x) (x&(-x))
#define Pb push_back
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
const int    prime = 999983;
const int    INF = 0x7FFFFFFF;
const LL     INFF =0x7FFFFFFFFFFFFFFF;
const double PI = acos(-1.0);
const double inf = 1e18;
const double eps = 1e-6;
const LL     mod = 1e9 + 7;
int dr[2][4] = {1,-1,0,0,0,0,-1,1};
typedef pair<int,int> P;
LL qpow(LL a,LL b){
    LL ans = 1;
    a %= mod;
    while( b > 0){
        if(b&1) ans = ans*a%mod;
        a = a*a%mod;
        b >>= 1;
    }
    return ans;
} 
const int maxn = 2e3+100;
LL fac[maxn],invfac[maxn];
void init(void){
    fac[0] = 1;
    invfac[0] = 1;
    for(int i = 1;i < maxn; ++i)
       fac[i] = fac[i-1]*i%mod,invfac[i] = qpow(fac[i],mod-2);    
}
int main(void)
{
   init();
   LL n,m;
   while(scanf("%lld %lld",&n,&m) != EOF){
         LL ans = (fac[m+n]*invfac[m]%mod*invfac[n]%mod);
         ans = ans*ans%mod;
         ans = ans - fac[m+n]*fac[m+n]%mod*invfac[n+1]%mod*invfac[n-1]%mod * invfac[m+1]%mod * invfac[m-1]%mod;
         ans = (ans%mod + mod)%mod;
         printf("%lld\n",ans);
   }     

   return 0;
} 

全部评论
请问这个定理,起点和终点到底怎么选啊,我看wiki很久都没有想明白
点赞 回复 分享
发布于 2018-07-21 10:04
等价的意思就是说 路径数相同 吧?
点赞 回复 分享
发布于 2018-07-23 12:03
行列式图片有问题,一个为n - 1一个为 m - 1
点赞 回复 分享
发布于 2018-08-22 18:42

相关推荐

不愿透露姓名的神秘牛友
11-27 10:28
点赞 评论 收藏
分享
努力学习的小绵羊:我反倒觉得这种挺好的,给不到我想要的就别浪费大家时间了
点赞 评论 收藏
分享
头像
11-27 14:28
长沙理工大学
刷算法真的是提升代码能力最快的方法吗?&nbsp;刷算法真的是提升代码能力最快的方法吗?
牛牛不会牛泪:看你想提升什么,代码能力太宽泛了,是想提升算法能力还是工程能力? 工程能力做项目找实习,算法也分数据结构算法题和深度学习之类算法
点赞 评论 收藏
分享
评论
7
2
分享
牛客网
牛客企业服务