[CodeForces-869C]The Intriguing Obsession
阿新 • • 發佈:2017-10-25
getchar() tdi mod nbsp print gui ret git while 我們最少可以連0條邊,最多可以連min(a,b)條邊,則只考慮紅點和藍點的總方案數為sum{C(a,k)*C(b,k)*(k!)|0<=k<=min(a,b)}。
對於三種情況都可以這樣算。
顯然這三種情況是不會相互影響的,因此直接將三個答案乘起來就好了。
題目大意:
有三種顏色的點,a個紅色,b個藍色,c個紫色。
現在你要連邊,保證相同顏色的點之間距離>=3,問有多少種合法的連邊方案。(不一定連通)
思路:
當加上去的邊不滿足條件時,無非是以下兩種情況:
1.同色點距離=1,同色邊直接相連。
2.同色點距離=2,某個點直接連向兩個不同的同色點。
我們可以將這個問題分為三個部分:
1.a個紅點和b個藍點之間的連邊方案。
2.b個藍點和c個紫點之間的連邊方案。
3.a個紅點和c和紫點之間的連邊方案。
假設我們要在a個紅色和b個藍色之間連k條邊,則總共有C(a,k)*C(b,k)*(k!)種方案。
對於三種情況都可以這樣算。
顯然這三種情況是不會相互影響的,因此直接將三個答案乘起來就好了。
1 #include<cstdio> 2 #include<cctype> 3 #include<algorithm> 4 typedef long long int64; 5 const int N=5001,mod=998244353; 6 inline intgetint() { 7 register char ch; 8 while(!isdigit(ch=getchar())); 9 register int x=ch^‘0‘; 10 while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^‘0‘); 11 return x; 12 } 13 int C[N][N]; 14 int main() { 15 for(register int i=0;i<N;i++) { 16 C[i][0]=1; 17 for(register int j=1;j<=i;j++) { 18 C[i][j]=(C[i-1][j-1]+C[i-1][j])%mod; 19 } 20 } 21 int a=getint(),b=getint(),c=getint(); 22 int ans1=0,ans2=0,ans3=0; 23 for(register int k=0,fact=1;k<=std::min(a,b);fact=(int64)fact*++k%mod) { 24 ans1=((int64)C[a][k]*C[b][k]%mod*fact%mod+ans1)%mod; 25 } 26 for(register int k=0,fact=1;k<=std::min(b,c);fact=(int64)fact*++k%mod) { 27 ans2=((int64)C[b][k]*C[c][k]%mod*fact%mod+ans2)%mod; 28 } 29 for(register int k=0,fact=1;k<=std::min(a,c);fact=(int64)fact*++k%mod) { 30 ans3=((int64)C[a][k]*C[c][k]%mod*fact%mod+ans3)%mod; 31 } 32 printf("%d\n",int((int64)ans1*ans2%mod*ans3%mod)); 33 return 0; 34 }
[CodeForces-869C]The Intriguing Obsession