zoj——3624 Count Path Pair
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了zoj——3624 Count Path Pair相关的知识,希望对你有一定的参考价值。
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 C. f 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 f 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的主要内容,如果未能解决你的问题,请参考以下文章
ZOJ-1610 Count the Colors ( 线段树 )
ZOJ - 1610 Count the Colors 线段树区间修改