【GDOI2016模拟3.16】装饰
Description
Sol
取反计算即可。
#include<bits/stdc++.h> #define mo 1000000007 #define N 500007 #define LL long long using namespace std; LL fac[N],ni[N],anw,ans; int m,b,g,r; LL c(int x,int y){ if (y>x) return 0; return fac[x]*ni[y]%mo*ni[x-y]%mo; } LL qsm(LL x,LL y=mo-2){ static LL anw; for (anw=1;y;y>>=1,x=x*x%mo) if (y&1) anw=anw*x%mo; return anw; } LL sol(int cnt){ LL ant=0; for (int odd=abs(b-g);odd<=cnt;odd+=2){ anw=c(cnt,odd); anw=anw*c(odd,odd+abs(b-g)>>1)%mo; anw=anw*c(max(b,g)-(odd+abs(b-g))/2+odd-1,cnt-1)%mo; anw=anw*qsm(2,cnt-odd)%mo; ant=(ant+anw)%mo; } cerr<<ant<<endl; return ant; } signed main () { fac[0]=1; for (int i=1;i<N;i++) fac[i]=fac[i-1]*i%mo; ni[N-1]=qsm(fac[N-1]); for (int i=N-1;i;i--) ni[i-1]=ni[i]*i%mo; scanf("%d%d%d%d",&m,&r,&g,&b); r=m-r; g=m-g; b=m-b; ans+=sol(r)+sol(r-1); swap(r,b); ans+=sol(r)+sol(r-1); swap(r,g); ans+=sol(r)+sol(r-1); // if (r>0) ans+=sol(r-1); // if (m>=2*r)ans+=2*sol(r); // if (m>2*r)ans+=sol(r+1); printf("%lld",ans*2%mo); return 0; }