码迷,mamicode.com
首页 > 其他好文 > 详细

zoj——3624 Count Path Pair

时间:2017-08-14 10:03:50      阅读:139      评论:0      收藏:0      [点我收藏+]

标签:div   out   and   var   http   nbsp   main   乘法   scanf   

Count Path Pair

Time Limit: 3 Seconds      Memory Limit: 65536 KB

You are given four positive integers m,n,p,q(p < m and q < n). There are four points A(0,0),B(p,0),C(m,q),D(m,n). Consider the path f from A to D and path g from B to Cf and g are always towards and parallel to the positive direction of one axis, and they can only change their direction on integer points(whose coordinates are both integers).

You are asked to count the number(mod 100000007) of pair (f,g) that and g have no intersection.

Input

There are multiple cases(less than 100). Each case is a line containing four integers m,n,p,q(m ≤ 100000 and n ≤ 100000).

Output

For each case, output a single line containing the right answer.

Sample Input

2 2 1 1
3 2 1 1

Sample Output

3
6

 

题目大意:从A到D与从B到C的路径中不相交的有多少条。

思路:

这道题比较恶心,读题目大约找了2位大佬读,看了大约有1个多小时才搞懂的题意。(ORZ)

唉。这道题我们要求不相交的条数,不过不想交直接求太复杂,所以转化为补集思想:不想交=所有-相交,我们求出相交的,然后用总条数减去相交的条数就好了!

但是问题来了,我们要怎样求总条数与相交的条数呢?!

总路径数是C(M+N,M)*C(Q+M-P,Q)。

然后相交的地方肯定是B与C构成的矩形当中。

我们可以考虑A到C以及B到D,他们的路径必定有相交的,而且相交的位置必定也在矩形当中。

而且相交之后你可以考虑成从A到C的路径改为从交点到D,就样就完成了转化。

结果便是C(M+N,M)*C(Q+M-P,Q)-C(N+M-P,N)*C(M+Q,M);(为什么,背公式!)

然而,这还不够,因为这道题让着取模啊!!!(靠,变态的题目、、、、、、)

没办法,还是要搞一搞的,据学长说在遇到排列组合取模的问题的时候可以求乘法逆元(模数为质数)(还记不记得我们之前在做乘法逆元的题的时候遇到过这样的题,这里粘一下那道题:http://www.cnblogs.com/z360/p/7327322.html)我们这里上公式:

(a/b)mod p=a*c mod p = (a mod p * c mod p)mod p(定义 c为b在mod p意义下的逆元)

这个地方好像可以用卢卡斯定理做、、、、、(然而蒟蒻并不会,做完这道题再学吧、、、、、、、(⊙o⊙)…)

好了,好像这样就差不多了。(然而蒟蒻表示做了一天啊!~~~~(>_<)~~~~)

mdzz 取模的地方写错了,硬是找了一天、、、、、

代码:

 

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define N 1000005
#define mod 100000007  
#define ll long long 
using namespace std;
ll ans,m,n,q,p,jie[N];
ll read()
{
    ll 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;
}
ll ins(ll n)
{
    jie[0]=1;
    for(ll i=1;i<n;i++)
     jie[i]=(jie[i-1]*i)%mod;
}
ll exgcd(ll a,ll b,ll &x,ll &y)
{
    if(b==0)
    {
        x=1,y=0;
        return a;
    }
    ll r=exgcd(b,a%b,x,y),tmp;
    tmp=x,x=y,y=tmp-a/b*y;
    return r;
}
ll c(ll a,ll b)
{
    ll sum;
    ll x,y;b=jie[b]%mod*jie[a-b]%mod;
    sum=jie[a]; 
    exgcd(b,mod,x,y);
    x=(mod+x%mod)%mod;
    sum=(sum%mod*x%mod)%mod;
    return sum;
}
int main()
{
    ins(N);
    while(~scanf("%lld",&m))
    {
        n=read(),p=read(),q=read();
        ans=((c(m+n,m)%mod*c((q+m-p),q)%mod)%mod-(c((n+m-p),n)%mod*c((m+q),m)%mod)+mod)%mod;
        printf("%lld\n",ans);
    }
    return 0;
}

 

zoj——3624 Count Path Pair

标签:div   out   and   var   http   nbsp   main   乘法   scanf   

原文地址:http://www.cnblogs.com/z360/p/7355144.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!