BZOJ[4767] 两双手
Posted Nawox
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ[4767] 两双手相关的知识,希望对你有一定的参考价值。
向量是可以被基地唯一分解的,然后就和昨天的T3一样了
在计算x_的时候居然没注意最大可以变成500000,然后最开始设的最大值是100000,然后就一直wa
Code
1 #include <cmath> 2 #include <cstdio> 3 #include <cstdlib> 4 #include <cstring> 5 #include <iostream> 6 #include <algorithm> 7 # define mod 1000000007 8 using namespace std; 9 typedef long long LL; 10 int n,m,K; 11 int N,M; 12 int ax,bx,ay,by; 13 LL jc[500010],njc[500010]; 14 LL ksm(LL a,LL b){ 15 LL ans=1; 16 while(b){ 17 if(b&1) ans*=a,ans%=mod; 18 b=b>>1; a*=a; a%=mod; 19 } 20 return ans; 21 } 22 void beg(){ 23 int lim=500000; jc[0]=1; 24 for(int i=1;i<=lim;i++) jc[i]=jc[i-1]*i%mod; 25 for(int i=0;i<=lim;i++) njc[i]=ksm(jc[i],mod-2); 26 } 27 LL C(int a,int b){ 28 LL ret=jc[a]*njc[b]%mod*njc[a-b]%mod; 29 return ret; 30 } 31 struct node{ 32 int x,y,x_,y_; 33 }g[510]; 34 bool cmp(const node a,const node b){ 35 if(a.x_==b.x_) return a.y_<b.y_; 36 return a.x_<b.x_; 37 } 38 void init(){ 39 scanf("%d%d%d",&n,&m,&K); 40 scanf("%d%d%d%d",&ax,&ay,&bx,&by); 41 for(int i=1;i<=K;i++) scanf("%d%d",&g[i].x,&g[i].y); 42 43 } 44 void cal(int x,int y,int &A,int &B){ 45 int s=x*by-y*bx,t=ax*by-ay*bx; 46 if(s%t) A=1000000; else A=s/t; 47 if(A<0 || A>N) A=1000000; 48 s=x*ay-y*ax,t=bx*ay-by*ax; 49 if(s%t) B=1000000; else B=s/t; 50 if(B<0 || B>M) B=1000000; 51 } 52 LL f[510]; 53 void work(){ 54 cal(n,m,N,M); 55 if(N==1000000 || M==1000000){cout<<0<<endl;return;} 56 for(int i=1;i<=K;i++){ 57 cal(g[i].x,g[i].y,g[i].x_,g[i].y_); 58 if(g[i].x_==1000000 || g[i].y_==1000000) g[i].x_=1000000,g[i].y_=1000000; 59 } 60 sort(g+1,g+K+1,cmp); int ji=K; 61 for(int i=1;i<=K;i++){ 62 if(g[i].x_>N || g[i].y_>M){ji=i-1; break;} 63 } 64 K=ji; 65 LL ans=C(N+M,N); 66 for(int i=1;i<=K;i++){ 67 f[i]=C(g[i].x_+g[i].y_,g[i].x_); 68 for(int j=i-1;j>=1;j--){ 69 if(g[j].y_>g[i].y_) continue; 70 f[i]=(f[i]-f[j]*C(g[i].x_-g[j].x_+g[i].y_-g[j].y_,g[i].x_-g[j].x_)%mod)%mod; 71 } 72 } 73 for(int i=1;i<=K;i++){ 74 ans=(ans-f[i]*C(N-g[i].x_+M-g[i].y_,N-g[i].x_)%mod)%mod; 75 } 76 if(ans<0) ans+=mod; 77 cout<<ans<<endl; 78 } 79 int main(){ 80 // freopen("a.in","r",stdin); 81 init(); 82 beg(); 83 work(); 84 }
以上是关于BZOJ[4767] 两双手的主要内容,如果未能解决你的问题,请参考以下文章