2014ACMICPC亚洲区西安站 F题 color (组合数学,容斥原理)

    xiaoxiao2022-06-25  227

    2014ACM/ICPC亚洲区西安站 F题 color (组合数学,容斥原理)

    传送门:https://vjudge.net/problem/129666/origin

    题意:

    有n个点m种颜料,问你用k种颜色,有多少种方法,使得相邻两点的颜色不一样

    题解:

    容斥+组合数

    我们很容易知道,用t种颜色去涂n个格子,方案数为\[ t*(t-1)^{n-1} \]

    并不是,因为我们可以这样想

    如果我选用最多的五种颜色1,2,3,4,5去染色的话,我们可以会染出1,2,1,2这样的结果

    而如果只用两种颜色1,2去染色的话,我们也会染出1,2,1,2这样的结果

    因此我们的答案是错误的

    也就是说,用k种颜色去染色的时候,我们的结果是包含了k,k-1,,,1种颜色染色的结果的

    因此我们需要容斥一下\[ 定义函数 f(i)为只使用i种颜色的方案数\\ 定义ans恰好用k种颜色时的答案\\ Sum=k*(k-1)^{n-1}\\ 那么ans+(f(1)U f(2)U f(3)....f(k-1))=Sum\\ ans=Sum-(f(1)U f(2)U f(3)....f(k-1))\\ f(i)=C_{k}^{i}*(k-i-1)^{n-1}\\ (f(1)U f(2)U f(3)....f(k))=\sum_{i=2}^{k}(-1)^{i} f(i) \] 举个例子:如果我们有4 4 4 这组数据\[ 当我们最多用四种颜色时\quad C_4^4*4*3^3\\ 当我们最多用三种颜色即有一种颜色没有用到时\quad C_4^3*3*2^3\\ 当我们最多用两种颜色即有两种种颜色没有用到时\quad C_4^2*2*1^3\\ 当我们最多用一种颜色即有三种种颜色没有用到时\quad C_4^1*1*0^3\\ ans= C_4^4*4*3^3-C_4^3*3*2^3+C_4^2*2*1^3-C_4^1*1*0^3=24 \]

    代码:

    /** *        ┏┓    ┏┓ *        ┏┛┗━━━━━━━┛┗━━━┓ *        ┃       ┃   *        ┃   ━    ┃ *        ┃ >   < ┃ *        ┃       ┃ *        ┃... ⌒ ...  ┃ *        ┃       ┃ *        ┗━┓   ┏━┛ *          ┃   ┃ Code is far away from bug with the animal protecting           *          ┃   ┃ 神兽保佑,代码无bug *          ┃   ┃            *          ┃   ┃        *          ┃   ┃ *          ┃   ┃            *          ┃   ┗━━━┓ *          ┃       ┣┓ *          ┃       ┏┛ *          ┗┓┓┏━┳┓┏┛ *           ┃┫┫ ┃┫┫ *           ┗┻┛ ┗┻┛ */ // warm heart, wagging tail,and a smile just for you! // // _ooOoo_ // o8888888o // 88" . "88 // (| -_- |) // O\ = /O // ____/`---'\____ // .' \| |// `. // / \||| : |||// \ // / _||||| -:- |||||- \ // | | \\ - /// | | // | \_| ''\---/'' | | // \ .-\__ `-` ___/-. / // ___`. .' /--.--\ `. . __ // ."" '< `.___\_<|>_/___.' >'"". // | | : `- \`.;`\ _ /`;.`/ - ` : | | // \ \ `-. \_ __\ /__ _/ .-` / / // ======`-.____`-.___\_____/___.-`____.-'====== // `=---=' // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // 佛祖保佑 永无BUG #include <set> #include <map> #include <deque> #include <queue> #include <stack> #include <cmath> #include <ctime> #include <bitset> #include <cstdio> #include <string> #include <vector> #include <cstdlib> #include <cstring> #include <iostream> #include <algorithm> using namespace std; typedef long long LL; typedef long long ll; typedef pair<LL, LL> pLL; typedef pair<LL, int> pLi; typedef pair<int, LL> pil;; typedef pair<int, int> pii; typedef unsigned long long uLL; #define ls rt<<1 #define rs rt<<1|1 #define lson l,mid,rt<<1 #define rson mid+1,r,rt<<1|1 #define bug printf("*********\n") #define FIN freopen("input.txt","r",stdin); #define FON freopen("output.txt","w+",stdout); #define IO ios::sync_with_stdio(false),cin.tie(0) #define debug1(x) cout<<"["<<#x<<" "<<(x)<<"]\n" #define debug2(x,y) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<"]\n" #define debug3(x,y,z) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<" "<<#z<<" "<<z<<"]\n" const double eps = 1e-8; const int mod = 1e9 + 7; const int maxn = 1e6 + 5; const int INF = 0x3f3f3f3f; const LL INFLL = 0x3f3f3f3f3f3f3f3f; LL qpow(LL n, LL m) { LL ans = 1; while(m) { if(m & 1) ans = ans * n % mod; n = n * n % mod; m >>= 1; } return ans; } LL inv[maxn]; void init() { inv[1] = 1; for(int i = 2; i < maxn; i++) { inv[i] = (mod - mod / i) * inv[mod % i] % mod; } } LL n, m, k; LL Cm[maxn], Ck[maxn]; void get_C(int k) { Ck[0] = Cm[0] = 1; for(int i = 1; i <= k; i++) { Cm[i] = Cm[i - 1] % mod * (m - i + 1) % mod * inv[i] % mod; Ck[i] = Ck[i - 1] % mod * (k - i + 1) % mod * inv[i] % mod; } } int main() { #ifndef ONLINE_JUDGE FIN #endif init(); int T; scanf("%d", &T); int cas = 1; while(T--) { scanf("%lld%lld%lld", &n, &m, &k); get_C(k); int flag = 1; LL tot = 0; for(LL i = k; i >= 1; i--) { tot = (tot + 1LL * flag * Ck[k - i] * (i) % mod * qpow(i - 1, n - 1) % mod + mod) % mod; flag = -1 * flag; } tot = (tot * Cm[k]) % mod; printf("Case #%d: %lld\n", cas++, tot); } return 0; } posted @ 2019-05-21 22:16 buerdepepeqi 阅读( ...) 评论( ...) 编辑 收藏

    最新回复(0)