题意:
答案对1e9+7取模。
数据范围:h,w<=1e5,n<=2e3
解法:
对黑点排序。
令d[i]表示从(1,1)到达第i个黑点(x,y),且不经过其他黑点的方案数,
如果(1,1)到(x,y)矩形内没有其他黑点,那么方案数为C(x-1+y-1,x-1)=C(x+y-2,x-1),
如果有其他黑点,考虑容斥,需要减掉(1,1)到(x,y)矩形内的黑点j到达当前点i的方案数
那么d[i]-=d[j]*C(xi-xj+yi-yj,xi-xj)。
O(n2)即可计算出结果。
code:
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define ll long long
#define PI pair<int,int>
const int maxm=2e5+5;
const int mod=1e9+7;
int fac[maxm],inv[maxm];
struct Node{
int x,y;
}e[maxm];
int d[maxm];//d[i]表示(1,1)到达第i个黑点,不经过任何其他黑点的方案数.
int n,m,k;
int ppow(int a,int b,int mod){
int ans=1%mod;a%=mod;
while(b){
if(b&1)ans=ans*a%mod;
a=a*a%mod;
b>>=1;
}
return ans;
}
void init(){
fac[0]=1;
for(int i=1;i<maxm;i++)fac[i]=fac[i-1]*i%mod;
inv[maxm-1]=ppow(fac[maxm-1],mod-2,mod);
for(int i=maxm-2;i>=0;i--)inv[i]=(i+1)*inv[i+1]%mod;
}
int C(int n,int m){
if(m<0||m>n)return 0;
return fac[n]*inv[m]%mod*inv[n-m]%mod;
}
signed main(){
init();
cin>>n>>m>>k;
for(int i=1;i<=k;i++){
cin>>e[i].x>>e[i].y;
}
e[++k]={n,m};//将(n,m)看作第k+1个黑点,那么d[k+1]就是答案
sort(e+1,e+1+k,[](Node a,Node b)->bool{
if(a.x==b.x)return a.y<b.y;
return a.x<b.x;
});
for(int i=1;i<=k;i++){
d[i]=C(e[i].x+e[i].y-2,e[i].x-1);
for(int j=1;j<i;j++){
if(e[j].x<=e[i].x&&e[j].y<=e[i].y){
d[i]-=d[j]*C(e[i].x-e[j].x+e[i].y-e[j].y,e[i].x-e[j].x)%mod;
d[i]%=mod;
}
}
}
cout<<(d[k]+mod)%mod<<endl;
return 0;
}