C - The Intriguing Obsession
CodeForces - 869C
— This is not playing but duty as allies of justice, Nii-chan!
— Not allies but justice itself, Onii-chan!
With hands joined, go everywhere at a speed faster than our thoughts! This time, the Fire Sisters — Karen and Tsukihi — is heading for somewhere they've never reached — water-surrounded islands!
There are three clusters of islands, conveniently coloured red, blue and purple. The clusters consist of a, b and c distinct islands respectively.
Bridges have been built between some (possibly all or none) of the islands. A bridge bidirectionally connects two different islands and has length 1. For any two islands of the same colour, either they shouldn't be reached from each other through bridges, or the shortest distance between them is at least 3, apparently in order to prevent oddities from spreading quickly inside a cluster.
The Fire Sisters are ready for the unknown, but they'd also like to test your courage. And you're here to figure out the number of different ways to build all bridges under the constraints, and give the answer modulo 998 244 353. Two ways are considered different if a pair of islands exist, such that there's a bridge between them in one of them, but not in the other.
Input
The first and only line of input contains three space-separated integers a, b and c (1 ≤ a, b, c ≤ 5 000) — the number of islands in the red, blue and purple clusters, respectively.
Output
Output one line containing an integer — the number of different ways to build bridges, modulo 998 244 353.
Examples Input
1 1 1
Output
8
Input
1 2 2
Output
63
Input
1 3 5
Output
3264
Input
6 2 9
Output
813023575
有三堆顔色分别為紅黃藍三色的島嶼,架橋,一個橋的距離為1.
要求:同色之間不能直接相連或者距離小于3,這句話的意思就是架橋的兩個端點隻能在不同的顔色之間選,且A堆中任一一個點隻能同時和一個B中的點連,這樣才能保證B集合中的點之間的距離小于3。
這樣看,選擇兩堆來架橋,最多隻能架 兩堆中島嶼數量較小的那個集合的總數 座橋,最少可以不架橋,這都符合題目的要求。
接下來就是選擇的問題了,假設要在A集合(總數為a) 和 B集合(總數為b)間架k座橋:在a中選k個點,有C(a取k)種情況,在b中選k個點,有C(b取k)種情況,兩個集合裡各選出k個點,第一個點可以有k種選擇,在第一個點選過後,第二個點有k-1種選擇……一直到最後一個點有一種選擇,哎選完點之後,最後還要乘上k的階乘。
注意這裡k最多隻能取到兩個集合中小的那個,是以在循環之前先排個序,設定循環上限為小的那個。
C(n,m)=C(n,n-m)=C(n-1,m-1)+C(n-1,m)
#include <iostream>
#include <algorithm>
#define ll long long
using namespace std;
const ll mod =998244353;
ll max1,max2,max3;
ll C[5007][5007];
ll tt[3];
ll jc[5007];
void maxn(ll a,ll b,ll c)//排序
{
tt[0]=a;
tt[1]=b;
tt[2]=c;
sort(tt,tt+3);
max3=tt[0];
max2=tt[1];
max1=tt[2];
}
ll f(ll a,ll b)//計算
{
ll res=0;
for(int i=0;i<=b;i++)
{
res+=(C[a][i]*C[b][i]%mod)*(jc[i]%mod);
res%=mod;
}
return res;
}
int main()
{
for(int i=0;i<=5005;i++)//預處理
{
C[i][i]=1;
C[i][0]=1;
for(int j=1;j<=i;j++)
{
C[i][j]=C[i-1][j]+C[i-1][j-1];
C[i][j]%=mod;
}
}
jc[0]=1;
for(int i=1;i<=5005;i++)
{
jc[i]=jc[i-1]*i;
jc[i]%=mod;
}
ll res;
ll res1=0,res2=0,res3=0;
int a,b,c;
cin>>a>>b>>c;
maxn(a,b,c);
res1=f(max1,max2);
res2=f(max1,max3);
res3=f(max2,max3);
res=(((res1*res2)%mod)*res3)%mod;
//cout<<res1<<res2<<res3<<endl;
cout<<res<<endl;
return 0;
}