My Blogs
[ARC176F] Colorful Star
感覺很考驗想象力和計數基本功 QWQ。
首先考慮給定了局面之後如何進行判定。考慮把覆蓋的過程倒著做:如果 \(i\) 旁邊有和它顏色相同的棋子,那它就可以變成任意的顏色,然後要求最終能不能 \(n\) 種顏色都只剩一種。
然後這個還是不太本質。考慮如果有一個能變成任意顏色的,可以把它變成周圍的另一個顏色,然後另一個顏色就能變成任意的顏色。
這樣可以看成是空位的移動。問題變成了:在棋盤上有 \(n\) 種顏色的棋子和若干個空位。當兩個同色棋子相遇的時候可以把其中一個變成空位,可以把棋子移動到相鄰的空位。問最後能不能每種棋子只剩一個且分別待在正確的鏈上。
進一步分析:考慮有多少個空格的時候,不論棋盤形態如何,都能消完。顯然把初始相鄰相同的消掉之後,接下來的相同顏色的消除操作(下稱合併)一定是在中間位置發生的。
考慮如果只剩一個,不合法當且僅當把空位移到中心點之後中心點周圍顏色全不相同。
如果只剩兩個,不合法當且僅當把空位移到中心點和它周圍的一個點之後,周圍顏色有 \(n-1\) 種,且第二圈全部都是剩下的一種顏色。
其中 \(x\) 表示空位。
如果剩下了大於等於三個,則可以發現,能夠透過若干個操作把周圍兩圈裡的任意兩個放到一起,判掉 \(n\leq 2\) 的情況後,透過抽屜原理得一定能繼續消,所以一定能消完。
接下來就是計數(下文中把圖看成一棵以中心點為根的樹):
-
初始沒有空位,答案是 \(n\times(n-1)^{nm}\)。
-
初始有一個空位,並且之後周圍的顏色全部不同,答案是 \(n!\times nm\times(n-1)^{n(m-1)}\)。其中 \(n!\) 表示把空格移到中間之後周圍的一圈數字的順序,\(nm\) 表示選擇哪個位置和其父親顏色相同。這樣用去了 \(n+1\) 個位置,剩下的位置隨便填。
-
初始有兩個空位,兩個空位都是相鄰相等的顏色消出來的。答案是 \(n!\times \binom {nm} 2(n-1)^{n(m-2)}\)。\(n!\) 還是確定顏色的順序,然後需要選兩個位置和父親相同,容易發現無論選哪兩個位置都是合法的,譬如假如選了靠近根的兩個點,那就代表這種情況:
其餘的情況可以自行腦補。
由於需要確保中心點周圍一圈都不同並且再外面一圈都是剩下的一種顏色,這樣會用去 \(n+(n-1)\) 個位置,然後選兩個和父親相同,剩下了 \(nm-2n\) 個位置的方案數的唯一要求就是不能和父節點相同,\(n-1\)。
- 初始有一個空位,把這個空位移到中間之後再生出一個空位。首先需要確定空位產生的位置 \(nm\),然後從 \(n-1\) 個子樹裡面選兩個臨近根的點作為兩個顏色相同,把空位移上來能消掉的。然後還要確定顏色順序的 \(n!\),最後剩下的位置仍然是 \(nm-2n\),所以答案為 \(n!\times nm\times\binom {n-1}2\times (n-1)^{n(m-2)}\)。
最後用總和減去這四種不合法的就是答案。需要特判 \(n=1,n=2\) 和 \(m=1\)。
int n,m,fr;
inline void mian()
{
read(n,m),fr=1;
for(int i=1;i<=n;++i)Mmul(fr,i);
if(n==1)return write(1);
if(n==2)return write(Cadd(Cmul(n,m),2));
if(m==1)
{
int all=power(n,n+1);
int x=Cmul(n,power(n-1,n));
Madd(x,Cmul(n,Cdel(fr,1)));
return write(Cdel(all,x));
}
int all=power(n,n*m+1);
int x0=Cmul(n,power(n-1,n*m));
int x1=Cmul(n,m,fr,power(n-1,n*m-n));
int x2=Cmul(n,fr,power(n-1,n*m-2*n),m,m-1,inv2);
Madd(x2,Cmul(fr,n,n-1,inv2,m,m,power(n-1,n*m-2*n)));
Madd(x2,Cmul(fr,n,n-1,n-2,inv2,power(n-1,n*m-2*n),m));
write(Cdel(all,x0,x1,x2));
}