$A$
$B$
$C$
$D$
$E$
总感觉做过的亚子,,,$QwQ$
首先发现到达每个点所需要的操作一和操作二的次数都是可以求出来的?考虑先求出总移动数,然后按总移动数排序.
然后到达某点的方案数就是$C(x,x+y)$-经过前面点的方案数.
最后答案就是总方案数-经过各点的方案数,$over$
View Code#include<bits/stdc++.h> using namespace std; #define il inline #define rg register #define gc getchar() #define ll long long #define int long long #define ri register int #define rb register bool #define rc register char #define rp(i,x,y) for(rg int i=x;i<=y;++i) #define my(i,x,y) for(rg int i=x;i>=y;--i) const int N=1000000+10,mod=1e9+7; int n,Sx,Sy,Ax,Ay,Bx,By,nod_cnt,jc[N],inv[N],f[N]; struct node{int x,y;}nod[N]; il int read() { rg char ch=gc;rg int x=0;rg bool y=1; while(ch!='-' && (ch>'9' || ch<'0'))ch=gc; if(ch=='-')ch=gc,y=0; while(ch>='0' && ch<='9')x=(x<<1)+(x<<3)+(ch^'0'),ch=gc; return y?x:-x; } il void cal(ri &x,ri &y) { ll a1,a2,b1,b2; a1=x*By-y*Bx;a2=Ax*By-Ay*Bx; b1=x*Ay-Ax*y;b2=Bx*Ay-Ax*By; if(a2==0||b2==0){x=-1;y=-1;return;} if((a1/a2)*a2!=a1||(b1/b2)*b2!=b1){x=-1;y=-1;return;} x=a1/a2;y=b1/b2; } il bool cmp(node gd,node gs){return gd.x==gs.x?gd.y<gs.y:gd.x<gs.x;} int C(int n,int m){if(n<m)return 0;return 1ll*jc[n]*inv[m]%mod*inv[n-m]%mod;} il int power(ri x,ri y){ri ret=1;while(y){if(y&1)ret=1ll*ret*x%mod;x=1ll*x*x%mod;y>>=1;}return ret;} signed main() { //freopen("1.in","r",stdin);freopen("E.out","w",stdout); Sx=read();Sy=read();n=read();Ax=read(),Ay=read(),Bx=read(),By=read();cal(Sx,Sy);nod[++nod_cnt]=(node){Sx,Sy}; rp(i,1,n){ri x=read(),y=read();cal(x,y);if(x>=0 && y>=0 && x<=Sx && y<=Sy)nod[++nod_cnt]=(node){x,y};} sort(nod+1,nod+1+nod_cnt,cmp); //rp(i,1,nod_cnt)printf("%d %d ",nod[i].x,nod[i].y); jc[0]=1;rp(i,1,N-10)jc[i]=1ll*jc[i-1]*i%mod; inv[N-10]=power(jc[N-10],mod-2);my(i,N-11,0)inv[i]=1ll*inv[i+1]*(i+1)%mod; rp(i,1,nod_cnt) { f[i]=C(nod[i].x+nod[i].y,nod[i].x); rp(j,1,i-1)f[i]=(f[i]-1ll*f[j]*C(nod[i].x-nod[j].x+nod[i].y-nod[j].y,nod[i].x-nod[j].x)%mod+mod)%mod; } printf("%lld ",f[nod_cnt]); return 0; }