• [CF997C] Sky Full of Stars


    前言

    T7猎天下第一!

    题目

    洛谷

    CF

    讲解

    这种题当然优先考虑容斥。

    没有什么思路的时候就直接写暴力式子然后试图优化它。

    首先我们先写出至少有一行或一列颜色相同的方案数:

    [2 imes sum_{i=1}^n(-1)^{i-1} imes C(n,i) imes 3^{n^2-in+i} ]

    行列等价,所以要乘 (2)

    但显然我们算重了既有行颜色相同又有列颜色相同的情况,所以我们要减掉它们,需要减掉的东西可以通过暴力枚举行列颜色相同个数表示出来:

    [sum_{i=1}^n (-1)^{i-1} imes 3 imes C(n,i) imes sum_{j=1}^n (-1)^{j-1} imes C(n,j) imes 3^{n^2-in-jn+ij} ]

    我们考虑把与 (j) 无关的东西提到前面并重新改写一下式子。

    [sum_{i=1}^n (-1)^{i-1} imes 3 imes C(n,i) imes 3^{n^2-in} imes sum_{j=1}^n (-1)^{j-1} imes C(n,j) imes (3^{i-n})^{j} ]

    后面有幂形式,又有组合数,你想到了什么?

    二项式定理!逆向使用!

    [egin{aligned} &sum_{i=1}^n (-1)^{i} imes 3 imes C(n,i) imes 3^{n^2-in} imes sum_{j=1}^n (-1)^{j} imes C(n,j) imes (3^{i-n})^{j}\ =&sum_{i=1}^n (-1)^{i} imes 3 imes C(n,i) imes 3^{n^2-in} imes sum_{j=1}^n C(n,j) imes (-3^{i-n})^{j}\ =&sum_{i=1}^n (-1)^{i} imes 3 imes C(n,i) imes 3^{n^2-in} imes sum_{j=1}^n C(n,j) imes 1^{n-j} imes(-3^{i-n})^{j}\ =&sum_{i=1}^n (-1)^{i} imes 3 imes C(n,i) imes 3^{n^2-in} imes (1-3^{i-n})^{j}\ end{aligned}]

    合理吗?

    不合理,上面的式子是错的!因为二项式定理是从零开始的,所以最终的答案应该为:

    [2 imes sum_{i=1}^n(-1)^{i-1} imes C(n,i) imes 3^{n^2-in+i}-sum_{i=1}^n (-1)^{i} imes 3 imes C(n,i) imes 3^{n^2-in} imes ((1-3^{i-n})^{j}-1) ]

    写这么详细是因为我这个cb在推式子的时候把二项式定理搞反了,调了很久。

    代码

    戳我
    //12252024832524
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #define TT template<typename T>
    using namespace std; 
    
    typedef long long LL;
    const int MAXN = 1000005;
    const int MOD = 998244353;
    const int inv3 = 332748118;
    LL n,ans;
    
    LL Read()
    {
    	LL x = 0,f = 1;char c = getchar();
    	while(c > '9' || c < '0'){if(c == '-')f = -1;c = getchar();}
    	while(c >= '0' && c <= '9'){x = (x*10) + (c^48);c = getchar();}
    	return x * f;
    }
    TT void Put1(T x)
    {
    	if(x > 9) Put1(x/10);
    	putchar(x%10^48);
    }
    TT void Put(T x,char c = -1)
    {
    	if(x < 0) putchar('-'),x = -x;
    	Put1(x); if(c >= 0) putchar(c);
    }
    TT T Max(T x,T y){return x > y ? x : y;}
    TT T Min(T x,T y){return x < y ? x : y;}
    TT T Abs(T x){return x < 0 ? -x : x;}
    
    int qpow(int x,LL y){int ret = 1;while(y){if(y & 1) ret = 1ll * ret * x % MOD;x = 1ll * x * x % MOD;y >>= 1;}return ret;}
    int fac[MAXN],ifac[MAXN];
    void init(int x)
    {
    	fac[0] = ifac[0] = 1;
    	for(int i = 1;i <= x;++ i) fac[i] = 1ll * fac[i-1] * i % MOD;
    	ifac[x] = qpow(fac[x],MOD-2);
    	for(int i = x-1;i >= 1;-- i) ifac[i] = ifac[i+1] * (i+1ll) % MOD;
    }
    LL C(int x,int y)
    {
    	if(x < y || y < 0) return 0;
    	return 1ll * fac[x] * ifac[y] % MOD * ifac[x-y] % MOD;
    }
    
    int main()
    {
    //	freopen(".in","r",stdin);
    //	freopen(".out","w",stdout);
    	n = Read();
    	init(n);
    	for(int i = 1;i <= n;++ i) ans = (ans + ((i & 1) ? 1 : -1) * C(n,i) * qpow(3,(n-i)*n+i)) % MOD;
    	ans = ans * 2ll % MOD;
    	for(int i = 1;i <= n;++ i)
    		ans = (ans - ((i & 1) ? -1 : 1) * 3 * C(n,i) * qpow(3,(n-i)*n) % MOD * (qpow(1-qpow(inv3,n-i),n)-1)) % MOD;
    	Put((ans+MOD)%MOD);
    	return 0;
    }
    
  • 相关阅读:
    图说jdk1.8新特性(3)--- 注解与类型推测优化
    图说jdk1.8新特性(2)--- Lambda
    图说jdk1.8新特性(1)--- 函数式接口
    Linux应用与端口
    Linu如何查看磁盘占用情况及处理办法
    ThreadLocal剧集(一)
    缓存穿透、缓存击穿、缓存雪崩区别和解决方案
    MySQL 新建用户,为用户授权,指定用户访问数据库
    2019面试总结
    Java的设计模式
  • 原文地址:https://www.cnblogs.com/PPLPPL/p/15103899.html
Copyright © 2020-2023  润新知