bzoj 3782: 上学路线
这和51nod 1486 那题是差不多的,只不过这里过了一个合数的取模,拆成素数然后用中国剩余定理合并起来就好
(说的好轻巧啊)
1 /*#include<bits/stdc++.h> 2 #define LL long long 3 using namespace std; 4 inline LL ra() 5 { 6 LL x=0; char ch=getchar(); 7 while (ch<'0' || ch>'9') ch=getchar(); 8 while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();} 9 return x; 10 } 11 12 LL p[]={3LL,5LL,6793LL,10007LL}; 13 14 struct node{ 15 LL x,y; 16 }a[500]; 17 bool cmp(node a, node b) {return a.x==b.x?a.y<b.y:a.x<b.x;} 18 19 const int maxn=1000005; 20 const int MAXN=10010; 21 22 LL fac[maxn],inv[maxn]; 23 LL FAC[4][MAXN],INV[4][MAXN]; 24 LL n,m,mod,T; 25 26 void pre() 27 { 28 if (mod==1000003) 29 { 30 fac[0]=1; 31 for (int i=1; i<maxn; i++) fac[i]=fac[i-1]*i%mod; 32 inv[0]=inv[1]=1; 33 for (int i=2; i<maxn; i++) inv[i]=(mod-mod/i)*inv[mod%i]%mod; 34 for (int i=2; i<maxn; i++) inv[i]=inv[i]*inv[i-1]%mod; 35 return; 36 } 37 for (int j=0; j<4; j++) 38 { 39 FAC[j][0]=1; 40 for (int i=1; i<MAXN; i++) FAC[j][i]=FAC[j][i-1]*i%p[j]; 41 INV[j][0]=INV[j][1]=1; 42 for (int i=2; i<MAXN; i++) INV[j][i]=(p[j]-p[j]/i)*INV[j][p[j]%i]%p[j]; 43 for (int i=2; i<MAXN; i++) INV[j][i]=INV[j][i-1]*INV[j][i]%p[j]; 44 } 45 // cout<<FAC[0][2]*INV[0][1]*INV[0][1]; 46 } 47 48 LL lucas1(LL n, LL m) 49 { 50 if (n<m) return 0; 51 if (n<mod && m<mod) return fac[n]*inv[m]%mod*inv[n-m]%mod; 52 return lucas1(n/mod,m/mod)*lucas1(n%mod,m%mod)%mod; 53 } 54 55 LL lucas2(LL n, LL m, int opt) 56 { 57 if (n<m) return 0;// cout<<n<<' '<<m<<' '<<FAC[opt][n]*INV[opt][m]%p[opt]*INV[opt][n-m]%p[opt]; system("pause"); 58 if (n<p[opt] && m<p[opt]) return FAC[opt][n]*INV[opt][m]%p[opt]*INV[opt][n-m]%p[opt]; 59 return lucas2(n/p[opt],m/p[opt],opt)*lucas2(n%p[opt],m%p[opt],opt)%p[opt]; 60 } 61 LL ksm(LL x, int p, int mod) 62 { 63 LL sum=1; 64 for (;p;p>>=1,x=x*x%mod) 65 if (p&1) sum=sum*x%mod; 66 return sum; 67 } 68 LL C(LL n, LL m) 69 { 70 // printf("%d %d %d\n",n,m,lucas1(n,m)); 71 if (mod==1000003) return lucas1(n,m); 72 else{ 73 LL ans=0; 74 for (int i=0; i<4; i++) 75 ans+=lucas2(n,m,i)*ksm(mod/p[i],p[i]-2,p[i])%mod*(mod/p[i])%mod,ans=(ans+mod)%mod; 76 return ans; 77 } 78 } 79 80 LL f[MAXN]; 81 82 int main() 83 { 84 n=ra(); m=ra(); T=ra(); mod=ra(); pre(); 85 for (int i=1; i<=T; i++) a[i].x=ra(),a[i].y=ra(); 86 a[++T].x=n; a[T].y=m; 87 sort(a+1,a+T+1,cmp); 88 for (int i=1; i<=T; i++) 89 { 90 f[i]=C(a[i].x+a[i].y,a[i].x);// cout<<a[i].x<<" "<<a[i].y<<" "<<f[i]<<endl; 91 for (int j=1; j<i; j++) 92 if (a[j].y<=a[i].y) 93 f[i]=(f[i]-C(a[i].x-a[j].x+a[i].y-a[j].y,a[i].x-a[j].x)*f[j]%mod+mod)%mod; 94 } 95 cout<<f[T]<<endl; 96 return 0; 97 }*/ 98 99 #include<bits/stdc++.h> 100 #define LL long long 101 using namespace std; 102 struct node{ 103 LL x,y; 104 }a[500]; 105 bool cmp(node a, node b){ 106 return a.x==b.x?a.y<b.y:a.x<b.x; 107 } 108 LL n,m,P; 109 LL p[10]; 110 LL fac[5][1000010],inv[5][1000010]; 111 LL f[1010]; 112 LL g[10],sum[10],INV[10]; 113 int num; 114 bool w=0; 115 LL ksm(LL x, LL y, LL p) 116 { 117 LL sum=1; 118 for (;y;y>>=1,x=x*x%P) 119 if (y&1LL) sum=sum*x%P; 120 return sum; 121 } 122 LL c(LL x, LL y, int i) 123 { 124 if (x<p[i] && y<p[i]) return fac[i][y]*inv[i][x]%p[i]*inv[i][y-x]%p[i]; 125 else return c(x%p[i],y%p[i],i)*c(x/p[i],y/p[i],i)%p[i]; 126 } 127 LL C(LL y, LL x) 128 { 129 if (!w) return c(x,y,0); 130 else 131 { 132 for (int i=1; i<=4; i++) g[i]=c(x,y,i); 133 LL ans=0; 134 for (int i=1; i<=4; i++) ans=(ans+(g[i]*sum[i])%P*INV[i]%P)%P; 135 return ans; 136 } 137 } 138 int main() 139 { 140 scanf("%lld%lld%lld%lld",&n,&m,&num,&P); 141 for (int i=1; i<=num; i++) scanf("%lld%lld",&a[i].x,&a[i].y); 142 a[++num].x=n; a[num].y=m; 143 sort(a+1,a+num+1,cmp); 144 if (P!=1000003) p[1]=3,p[2]=5,p[3]=6793,p[4]=10007,w=1; else p[0]=1000003; 145 if (w) 146 { 147 for (int j=1; j<=4; j++) 148 { 149 fac[j][0]=1; sum[j]=P/p[j]; INV[j]=ksm(sum[j],p[j]-2,p[j]); 150 for (int i=1; i<p[j]; i++) fac[j][i]=fac[j][i-1]*i%p[j]; 151 inv[j][p[j]-1]=ksm(fac[j][p[j]-1],p[j]-2,p[j]); 152 for (int i=p[j]-2; i>=0; i--) inv[j][i]=inv[j][i+1]*(i+1)%p[j]; 153 } 154 } 155 else 156 { 157 fac[0][0]=1; 158 for (int i=1; i<P; i++) fac[0][i]=fac[0][i-1]*i%P; 159 inv[0][P-1]=ksm(fac[0][P-1],P-2,P); 160 for (int i=P-2; i>=0; i--) inv[0][i]=inv[0][i+1]*(i+1)%P; 161 } 162 for (int i=1; i<=num; i++) 163 { 164 f[i]=C(a[i].x+a[i].y,a[i].x); 165 for (int j=1; j<i; j++) 166 if (a[i].y>=a[j].y) 167 f[i]=(f[i]-f[j]*C(a[i].x-a[j].x+a[i].y-a[j].y,a[i].x-a[j].x)%P+P)%P; 168 } 169 cout<<f[num]; 170 return 0; 171 }