After winning the silver medal, OI master shiver smoothly escorted PKU. On this day, shua'er asked the elder, "although I have already been escorted, I still have to take the entrance examination. I'm going to take the political exam soon. How can I study philosophy and pass the political exam? "
The elder replied, "Oh, you, too young too simple, sometimesnaive! Philosophy is not something that you can understand if you want to understand it. You need to be quiet and tear it. You go to the back forest and think about it. "
There is a forest of philosophy and learning in the elder's backyard. For some mysterious reasons, the forest forms a n*m rectangle, in which each point represents a tree. In addition, some trees were uprooted (i.e. disappeared) due to the trouble of little C, the person who wrote the question of spicy chicken. Every day, he wants to think under the tree, so he wants to choose a tree in each row. But he hated to go back, so the tree on line I had to be to the right of line i-1. Now he wants to know how many options there are.
This is the same: but pay attention to the particularity of the interference point
So it's set to X-1,Y-1
In this way, the next step must be the interference point
Then DP
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> using namespace std; typedef int INT; #define int long long const int N=2010; const int mod=1000003; inline int Quick_Pow(int x,int k){ int ret=1; while(k){ if(k%2){ ret=ret*x%mod; } k/=2; x=x*x%mod; } return ret; } struct Node{ int x,y; }A[N]; int fac[mod+1]; int inv[mod+1]; int n,m,q; int G[2010][2010]; int F[2010]; bool cmp(Node A,Node B){ return A.y<B.y||(A.y==B.y&&A.x<B.x); } void Pre(){ fac[0]=1; for(int i=1;i<mod;++i){ fac[i]=fac[i-1]*i%mod; } inv[mod-1]=Quick_Pow(fac[mod-1],mod-2); for(int i=mod-2;i>=0;--i){ inv[i]=inv[i+1]*(i+1)%mod; } } int C(int n,int m){ if(m>n)return 0; return fac[n]*inv[m]%mod*inv[n-m]%mod; } int Lucas(int n,int m){ if(!m)return 1; return Lucas(n/mod,m/mod)*C(n%mod,m%mod)%mod; } void Build(){ for(int i=0;i<=q;++i){ for(int j=i+1;j<=q;++j){ if(A[j].x>A[i].x&&A[j].y>A[i].y) G[i][j]=Lucas(A[j].y-A[i].y-1,A[j].x-A[i].x-1); } } } INT main(){ Pre(); scanf("%lld%lld%lld",&n,&m,&q); for(int i=1;i<=q;++i){ scanf("%lld%lld",&A[i].x,&A[i].y); } q++; A[0].x=0; A[0].y=0; A[q].x=n+1; A[q].y=m+1; sort(A+1,A+1+q,cmp); Build(); for(int i=1;i<=q;++i){ F[i]=G[0][i]; for(int j=1;j<i;++j){ if(A[i].x>A[j].x&&A[i].y>A[j].y) F[i]=((F[i]-G[j][i]*F[j]%mod)+mod)%mod; } // cout<<F[i]<<" "; } // cout<<G[2][3]; cout<<F[q]; }