【容斥+组合数】Massage @2018acm徐州邀请赛 E

 

问题 E: Massage

时间限制: 1 Sec  内存限制: 64 MB

题目描述

JSZKC  feels  so  bored  in  the  classroom  that  he  wants  to  send  massages  to  his  girl  friend. However, he can’t move to his girl friend by himself. So he has to ask his classmates for help. 
The classroom is a table of size N × M. We'll consider the table rows numbered from top to bottom 1 through N, and the columns numbered from left to right 1 through M. Then we'll denote the cell in row x and column y as (x, y). And every cell sits a student. 
Initially JSZKC sits on the cell (1, 1) . And his girl friend sits on cell (n, m). A message can go from  cell (x, y) to  one  of  two  cells (x + 1, y) and (x, y + 1).  JSZKC  doesn’t  want  to  trouble  his classmates too much. So his classmates(not including his girl friend) may not take massages more than once. It’s obvious that he can only send out two massages. Please help JSZKC find the number of ways in which the two massages can go from cell (1, 1) to cell (n, m). 
More  formally,  find  the  number  of  pairs  of  non-intersecting  ways  from  cell (1, 1) to cell (n, m) modulo 1000000007 .  Two  ways  are  called  non-intersecting  if  they  have  exactly  two common points — the starting point and the final point. 

输入

The input file contains several test cases, each of them as described below. 
The first line of the input contains one integers N (2 ≤ N,M≤ 1000), giving the number of rows and columns in the classroom. 
There are no more than 100 test cases. 

输出

One line per case, an integer indicates the answer mod 1000000007. 

样例输入

2 2
2 3
3 3

样例输出

1
1
3

 

meaning

从(1,1)到(n,m)只能向(x+1,y)和(x,y+1)走,问有多少种方案走两条不相交的路。

solution

又是一道想到了就很水的题

要求走两条路且不相交,可以将起点看作A1(1,2)和A2(2,1),终点看作B1(n-1,m)和B2(n,m-1)。

设S(A,B)表示从A到B的方案数。(C(n+m-2,n-1),n,m为矩形长宽)

那么由容斥,ans = S(A1,B1)*S(A2,B2)-S(A1,B2)*S(A2,B1) (因为只要路径相交,从A1就可以到B2,从A2就可以到B1)

code

#define IN_LB() freopen("C:\\Users\\acm2018\\Desktop\\in.txt","r",stdin)
#define OUT_LB() freopen("C:\\Users\\acm2018\\Desktop\\out.txt","w",stdout)
#define IN_PC() freopen("C:\\Users\\hz\\Desktop\\in.txt","r",stdin)
#include <bits/stdc++.h>
using namespace std;
 
typedef long long ll;
const int maxn = 200005;
ll fac[maxn],MOD = 1e9+7;
 
void init() {
    int i;
    fac[0] =1;
    for(i =1; i <= (int)2e5+10; i++) //modify
        fac[i] = fac[i-1]*i % MOD;
}
 
ll fastpow(ll a, ll b) {
    ll tmp = a % MOD, ans =1;
    while(b) {
        if(b &1)
            ans = ans * tmp % MOD;
        tmp = tmp*tmp % MOD;
        b >>=1;
    }
    return ans;
}
 
ll comb(ll n, ll m) {
    return  m>n ? 0 : fac[n]*fastpow(fac[m]*fac[n-m], MOD-2) % MOD;
}
 
ll Lucas(ll n, ll m) {
    return m ? (comb(n%MOD, m%MOD)*Lucas(n/MOD, m/MOD))%MOD : 1;
}
 
int main() {
//    IN_LB();
    init();
    int n,m;
    while(scanf("%d%d",&n,&m)!=EOF){
        cout<<(Lucas(n+m-4,n-2)*Lucas(n+m-4,n-2)%MOD-Lucas(n+m-4,n-1)*Lucas(n+m-4,m-1)%MOD+MOD)%MOD<<endl;
    }
    return 0;
}


posted @ 2018-06-06 10:34  NeilThang  阅读(216)  评论(0编辑  收藏  举报