BZOJ 3782 上学路线
Posted ziliuziliu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ 3782 上学路线相关的知识,希望对你有一定的参考价值。
首先这个题需要dp.dp[i]=C(x[i]+y[i],x[i])-Σdp[j]*C(x[i]-x[j]+y[i]-y[j],x[i]-x[j])(x[i]>=x[j],y[i]>=y[j])。
然后就是喜闻乐见的lucas+CRT.
#include<iostream> #include<cstring> #include<cstdio> #include<algorithm> #define maxn 1000050 using namespace std; long long n,m,t,mod,p[5],ans[5],inv1[5][maxn],inv2[5][maxn],up,f[300],a[5]; struct pnt { long long x,y; }pt[300]; bool cmp(pnt x,pnt y) { if (x.y!=y.y) return x.y<y.y; return x.x<y.x; } long long f_pow(long long x,long long y,long long mod) { long long ans=1,base=x; while (y) { if (y&1) ans=(ans*base)%mod; base=(base*base)%mod; y>>=1; } return ans; } void get_mod(long long type) { up=type; if (type==1) { p[1]=1000003;inv1[1][0]=1;inv2[1][0]=1; for (long long i=1;i<=p[1]-1;i++) { inv1[1][i]=inv1[1][i-1]*i%p[1]; inv2[1][i]=f_pow(inv1[1][i],p[1]-2,p[1]); } } else { p[1]=3;p[2]=5;p[3]=6793;p[4]=10007; for (long long i=1;i<=4;i++) { inv1[i][0]=1;inv2[i][0]=1; for (long long j=1;j<=p[i]-1;j++) { inv1[i][j]=inv1[i][j-1]*j%p[i]; inv2[i][j]=f_pow(inv1[i][j],p[i]-2,p[i]); } } } } long long comb(long long n,long long m,long long p,long long type) { if (n<m) return 0; return inv1[type][n]*inv2[type][m]%p*inv2[type][n-m]%p; } long long lucas(long long n,long long m,long long p,long long type) { if (!m) return 1; return comb(n%p,m%p,p,type)*lucas(n/p,m/p,p,type)%p; } long long CRT() { long long ret=0; for (long long i=1;i<=up*up;i++) ret=(ret+a[i]*(mod/p[i])%mod*f_pow(mod/p[i],p[i]-2,p[i])%mod)%mod; return ret%mod; } long long get_C(long long n,long long m) { for (long long i=1;i<=up*up;i++) a[i]=lucas(n,m,p[i],i); return CRT(); } int main() { scanf("%lld%lld%lld%lld",&n,&m,&t,&mod); for (long long i=1;i<=t;i++) scanf("%d%d",&pt[i].x,&pt[i].y); if (mod==1000003) get_mod(1);else get_mod(2); sort(pt+1,pt+t+1,cmp);t++;pt[t].x=n;pt[t].y=m; for (long long i=1;i<=t;i++) { f[i]=get_C(pt[i].x+pt[i].y,pt[i].x); for (long long j=1;j<=i-1;j++) { if (pt[j].x<=pt[i].x && pt[j].y<=pt[i].y) f[i]=(f[i]-f[j]*get_C(pt[i].x-pt[j].x+pt[i].y-pt[j].y,pt[i].x-pt[j].x)%mod+mod)%mod; } } printf("%lld\n",(f[t]+mod)%mod); return 0; }
以上是关于BZOJ 3782 上学路线的主要内容,如果未能解决你的问题,请参考以下文章
bzoj3782&luogu4478 [BJWC2018]上学路线