AGC 051 D C4 题解
Posted Gary2005
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AGC 051 D C4 题解相关的知识,希望对你有一定的参考价值。
AGC 051 D C4 题解
首先这个图是一个二分图,可以将路径看成一个一个首尾相连的来回。
有以下几种来回:
- 从一个点出发回到自己(4种),数量记为\\(a,b,c,d\\)
- 从一个点出发到达另一个点,数量记为\\(e,f\\)。
如果直接解方程的话,就会有\\(2\\)个自由元,不妨令其为\\(e,f\\)。
不过把式子列出来,\\(a,b,c,d,e,f\\)的贡献只和\\(e,f,e+f\\)有关,所以可以用fft优化。
时间复杂度为\\(O(N\\log N)\\)。
code:
(namespace 里的部分可以看我以前的博客)
using namespace mypoly;
const int MAXN=1e6+5;
vector<int> f1,f2;
int fact[MAXN<<1],ifact[MAXN<<1];
int comb(int A,int B){
return 1ll*fact[A]*ifact[B]%MOD*ifact[A-B]%MOD;
}
int main(){
fact[0]=1;
rb(i,1,2000000) fact[i]=1ll*fact[i-1]*i%MOD;
ifact[2000000]=inv(fact[2000000]);
rl(i,2000000-1,0) ifact[i]=1ll*(i+1)*ifact[i+1]%MOD;
int b,d,c,a;
cin>>b>>d>>c>>a;
f1.resize(min(a,c)+1);
f2.resize(min(b,d)+1);
if((a&1)==(b&1)&&(a&1)==(c&1)&&(a&1)==(d&1));
else{
puts("0");
return 0;
}
rb(e,0,min(a,c)){
if((e&1)==(a&1)){
f1[e]=1ll*ifact[e]*ifact[(a-e)>>1]%MOD*ifact[(c-e)>>1]%MOD;
}
}
rb(f,0,min(b,d)){
if((f&1)==(b&1)){
f2[f]=1ll*ifact[f]*ifact[(b-f)>>1]%MOD*ifact[(d-f)>>1]%MOD;
}
}
f1=f2*f1;
int rest=0;
rep(i,f1.size()){
if(i&1) continue;
int val=f1[i];
val=1ll*val*fact[i]%MOD;
val=1ll*val*fact[(a+b-i)>>1]%MOD;
val=1ll*val*fact[(c+d-i)>>1]%MOD;
int t=i/2+1,r=i/2;
int A=(a+b-i)/2;
int B=(c+d-i)/2;
val=1ll*val*comb(A+t-1,t-1)%MOD;
val=1ll*val*comb(B+r-1,r-1)%MOD;
(rest+=val)%=MOD;
}
printf("%d\\n",rest);
return 0;
}
以上是关于AGC 051 D C4 题解的主要内容,如果未能解决你的问题,请参考以下文章