RT,调了一晚上,不知道哪里错了,特来求助谷内大佬。本代码有两种方法求逆元,均经过ExLucas的验证是对的。
CF#4数据:
Input
100000 100000 4
50001 50001
50000 50000
50000 50001
50001 50000
Output
896312953
Answer
999612315
代码如下:
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#define int long long
using namespace std;
const int N=1e6+10;
const int mod=1e9+7;
struct node{
int x,y;
}pos[N];
bool cmp(node a,node b){
if(a.x==b.x){
return a.x<b.x;
}
return a.x<b.x;
}
long long jc[N],ans,f[N],inv[N];
long long pow(long long y,long long z,long long p){
long long res=1;
while(z){
if(z&1) res=(res*y)%p;
y=(y*y)%p;
z>>=1;
}
return (res%p+p)%p;
}
long long exgcd(long long a,long long b,long long &x,long long &y){
if(b==0){
x=1,y=0;
return a;
}
long long gcd=exgcd(b,a%b,x,y);
long long z=x;x=y;y=z-(a/b)*y;
return gcd;
}
long long inverse(long long n,long long p){
long long x=0,y=0;
exgcd(n,p,x,y);
return (x%p+p)%p;
}
long long C(int m,int n){
if(m>n){
return 0;
}
return (long long)(1ll*jc[n]*inv[n-m]%mod*inv[m]%mod+mod)%mod;
}
signed main(){
long long h,w,n;
scanf("%lld%lld%lld",&h,&w,&n);
for(int i=1;i<=n;i++){
scanf("%lld%lld",&pos[i].x,&pos[i].y);
}
pos[n+1].x=h,pos[n+1].y=w;
sort(pos+1,pos+n+2,cmp);
jc[0]=1,inv[0]=1;
for(int i=1;i<=h+w+h+w;i++){
jc[i]=jc[i-1]*i%mod;
inv[i]=pow(jc[i],mod-2,mod);
}
for(int i=1;i<=n+1;i++){
f[i]=(C(pos[i].x-1,pos[i].x+pos[i].y-2)%mod+mod)%mod;
for(int j=1;j<i;j++){
f[i]-=f[j]*C((pos[i].x-pos[j].x),(pos[i].x+pos[i].y-pos[j].x-pos[j].y))%mod;
f[i]=(f[i]%mod+mod)%mod;
}
f[i]=(f[i]%mod+mod)%mod;
}
printf("%lld\n",(f[n+1]%mod+mod)%mod);
}