首先一个向量可以被两个向量唯一表示 然后就转化为有障碍点的网格图路径计数
这应该是个经典的容斥模型 果然是NOIP模拟赛啊
如果不考虑障碍 那么答案是
path(s,t)=Cmn+m
然后我们考虑容斥 枚举路径上碰到的第一个障碍点
v
其中 fv 表示从起点 s 出发不经过其他障碍点到达
fv 怎么求 从头开始DP就好了
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<set>
#define read(x) scanf("%d",&(x))
using namespace std;
typedef pair<int,int> abcd;
typedef long long ll;
const int P=1e9+7;
const int MAXN=1000005;
ll fac[MAXN],inv[MAXN];
inline void Pre(int n=500000){
fac[0]=1; for (int i=1;i<=n;i++) fac[i]=fac[i-1]*i%P;
inv[1]=1; for (int i=2;i<=n;i++) inv[i]=(ll)(P-P/i)*inv[P%i]%P;
inv[0]=1; for (int i=1;i<=n;i++) inv[i]=inv[i]*inv[i-1]%P;
}
inline ll C(int n,int m){
return fac[n]*inv[m]%P*inv[n-m]%P;
}
int ex,ey,ax,ay,bx,by;
inline bool calc(int x,int y,int &A,int &B){
int s=x*by-y*bx,t=ax*by-ay*bx;
if (s%t) return 0; else A=s/t;
s=x*ay-y*ax,t=bx*ay-by*ax;
if (s%t) return 0; else B=s/t;
return 1;
}
const int N=505;
#define X first
#define Y second
int n,m;
int tot; abcd pt[N];
int f[N];
inline ll path(int j,int i){
int dx=pt[i].X-pt[j].X;
int dy=pt[i].Y-pt[j].Y;
if (dx<0 || dy<0) return 0;
return C(dx+dy,dx);
}
int main(){
int A,B; int x,y; Pre();
freopen("t.in","r",stdin);
freopen("t.out","w",stdout);
read(ex); read(ey); read(tot);
read(ax); read(ay); read(bx); read(by);
if (!(calc(ex,ey,A,B) && A>=0 && B>=0))
return printf("0\n"),0;
else
n=A,m=B;
int tmp=tot; tot=0;
for (int i=1;i<=tmp;i++){
read(x); read(y);
if (calc(x,y,A,B) && A>=0 && B>=0 && A<=n && B<=m)
pt[++tot]=abcd(A,B);
}
pt[++tot]=abcd(n,m);
sort(pt+1,pt+tot+1);
f[0]=1;
for (int i=1;i<=tot;i++){
f[i]=path(0,i);
for (int j=1;j<i;j++)
f[i]=(f[i]+P-(ll)f[j]*path(j,i)%P)%P;
}
printf("%d\n",f[tot]);
return 0;
}