棋盤是乙個n×m的矩形,分成n行m列共n*m個小方格。現在萌萌和南南有c種不同顏色的顏料,他們希望把棋盤用這些顏料染色,並滿足以下規定:
1. 棋盤的每乙個小方格既可以染色(染成c種顏色中的一種) ,也可以不染色。
2. 棋盤的每一行至少有乙個小方格被染色。
3. 棋盤的每一列至少有乙個小方格被染色。
4. 種顏色都在棋盤上出現至少一次。
以下是一些將3×3棋盤染成c = 3種顏色(紅、黃、藍)的例子:
請你求出滿足要求的不同的染色方案總數。只要存在乙個位置的顏色不同,
即認為兩個染色方案是不同的
輸入只有一行 3 個整數n,m,c。1 < = n,m,c < = 400
輸出乙個整數,為不同染色方案總數。因為總數可能很大,只需輸出總數
mod 1,000,000,007的值。
2 2 3
60~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
數論+思路~
設有i行j列k顏色是可能存在的,那麼此時的種類數為0<=i<=n,0<=j<=m,0<=k<=c,c[i][n]*c[j][m]*c[k][c]*(k+1)^(i*j)*(-1)^(n+m+c-i-j-k)。
這樣o(nmc)的演算法據說可以卡過……但是我被卡常了……
我們將有j的項提取出來,得到0<=i<=n,0<=j<=m,0<=k<=c,
(-1)^(n+m+c-i-k)
* c[i][n] * c[k][c] * ((k+1)^i)^j *
c[j][m]
*(-1)^(-j),
注意到後面包含j的項剛好是(1-k)^n的展開的形式。
所以原式可化簡為0<=i<=n,0<=k<=c,
(-1)^(n+m+c-i-k)
* c[i][n] * c[k][c] *(1-(k+1)^i)^m。
另:取模這個東西真是莫名其妙……wa了半天結果是先乘了-1^k後取模……所以遇到這種情況要先取模再乘啊……
被卡常的**:
#include#define ll long long
#define modd 100000007
int n,m,cc,c[401][401],ans;
int read()
while(ch>='0' && ch<='9')
return x*f;
}int mi(int u,int v)
return now;
}int main()
for(int i=0;i<=n;i++)
for(int j=0;j<=m;j++)
for(int k=0;k<=cc;k++) ans=((ll)ans+(ll)mi(-1,n+m+cc-i-j-k)*c[n][i]*c[m][j]*c[cc][k]*mi(k+1,i*j))%modd;
printf("%d\n",ans);
return 0;
}
a了的**:
#include#define ll long long
#define modd 1000000007
int n,m,cc;
ll c[401][401],ans;
int read()
while(ch>='0' && ch<='9')
return x*f;
}ll mi(ll u,ll v)
return now;
}ll kk(ll u)
int main()
for(int i=0;i<=n;i++)
for(int k=0;k<=cc;k++)
printf("%lld\n",ans);
return 0;
}
bzoj 4487 Jsoi2015 染色問題
問在n m 的網格圖上染色,要求每一行,每一列至少有乙個格被染色,且每種顏色至少出現一次,問方案數。今天腦子非常不清醒,想這種容斥裸題都想了半天 一開始還寫了個n3 的。直接做不好做,顯然要容斥,有三個限制,其中兩個容斥,剩下乙個算時候保證合法。我先對列容斥,設f i 表示最多有 i 列有格仔被染色...
BZOJ4487 JSOI2015 染色問題
link 普及題。容斥二項式反演得到答案的計算公式 sum limits n sum limits m sum limits c 1 k 1 這樣我們就可以 o nmc 地完成了。然後隨便優化一下就是 sum limits n sum limits c 1 k 1 i 1 m 這樣我們就可以 o n...
bzoj4487 Jsoi2015 染色問題
隔壁rose爺爺 這個隨便容斥一下寫完就過了 我 我的做法很菜雞,首先顏色給它變成最多用多少,然後再容斥 然後搞二維你設f i j 為i行為0j列為0的數量,再考慮容斥 會發現乙個很像二維二項式反演的東西。我不知道能不能直接用啊 捂臉,那就設了個類似字首和帶上組合數的東西,先反演出這個,再反演出f ...