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 }
View Code

 

以上是关于BZOJ[4767] 两双手的主要内容,如果未能解决你的问题,请参考以下文章

Bzoj4767 两双手

bzoj4767 两双手

BZOJ[4767] 两双手

[BZOJ 4767]两双手(组合数学+Dp)

BZOJ 4767 两双手

bzoj 4767 两双手 - 动态规划 - 容斥原理