• ARC139F Many Xor Optimization Problems【组合计数,qanalog】


    给定正整数 \(n,m\),考虑所有 \(2^{nm}\) 个长为 \(n\) 且每个元素小于 \(2^m\) 的非负整数序列,求最大子序列异或和之和 \(\bmod 998244353\)

    \(n,m\le 2.5\cdot 10^5\)


    前置知识:q-二项式系数

    参考了 wlzhouzhuan 的题解

    枚举所有 \(\mathbb F_2^m\) 的线性子空间,其贡献为生成它的序列个数乘上最大元素。

    引理. 长为 \(n\)\(\mathbb F_2^k\) 向量序列生成的线性空间即为 \(\mathbb F_2^k\) 的方案数为 \(\prod_{i=0}^{k-1}(2^n-2^i)\)

    转置一下即为长为 \(k\)\(\mathbb F_2^n\) 向量序列线性无关的方案数。

    所以枚举线性子空间的秩 \(k\),为了求出最大元素我们还需要枚举主元,设其从低到高分别为 \(a_1,\cdots,a_k\)

    取线性子空间的标准基底(即每个主元都只有对应向量有值),最大元素即为所有基的异或和,所以最大元素的主元位置都为 \(1\),非主元各有 \(1/2\) 的概率为 \(1\),所以期望值为 \(2^{a_k}+\sum_{i=1}^k2^{a_i-1}-\frac 12\)。而主元对应的线性空间(也即标准基底)数量为 \(\prod_{i=1}^k2^{a_i-(i-1)}\),把这三项乘起来再求和就是答案。

    接下来就是纯纯推柿子了。先把 \(2^{-\binom k2}\) 提出来,把期望值的三项拆开分别算。

    先看最后一项:\([x^k]\prod_{i=0}^{m-1}(1+2^ix)\),熟练的选手都知道这是 \(2^{\binom k2}\binom mk_2\),不熟练的话对比一下递推公式(?

    看中间一项:还要乘上 \(\sum_{i=1}^k2^{a_i}\),一个比较智慧的推法是总的 \(2^m-1\) 减去再选一个的贡献,也就是 \((2^m-1)2^{\binom k2}\binom mk_2-(k+1)2^{\binom{k+1}2}\binom m{k+1}_2\)

    看第一项,还要乘上 \(2^{a_k}\),所以要枚举 \(i=a_k\),也就是下面这个柿子:

    \[\begin{aligned} \text{Ans}&=\sum_{k=1}^{\min(n,m)}\left(2^\binom{k-1}2\color{#ff00ff}{\sum_{i=k-1}^{m-1}2^{2i}\binom{i}{k-1}_2}+\color{blue}{(2^{m-1}-1)}2^\binom k2\binom mk_2-(k+1)2^{\binom{k+1}2\color{blue}{-1}}\binom m{k+1}_2\right)2^{-\binom k2}\prod_{i=0}^{k-1}(2^n-2^i) \\ &=\frac 12\sum_{k=1}^{\min(n,m)}\left((2^{m+1}-1-2^{m-k})\binom{m}k_2-(k2^{k}+1)\binom m{k+1}_2\right)\prod_{i=0}^{k-1}(2^n-2^i) \end{aligned} \]

    这个粉色柿子需要观察一下,实际上是一个经典的吸收恒等式 + 上指标求和。

    \[\begin{aligned} \sum_{i=k}^{m-1}2^{2i}\binom ik_2&=2^{k-1}\sum_{i=k}^{m-1}(2^{i+1}-1)\cdot 2^{i-k}\binom{i}{k}_2+2^{k-1}\sum_{i=k}^{m-1}2^{i-k}\binom{i}{k}_2\\ &=(2^{2k}-2^{k-1})\sum_{i=k}^{m-1}2^{i-k}\binom{i+1}{k+1}_2+2^{k-1}\sum_{i=k}^{m-1}2^{i-k}\binom ik_2 \\ &=(2^{2k}-2^{k-1})\binom{m+1}{k+2}_2+2^{k-1}\binom{m}{k+1}_2 \end{aligned} \]

    时间复杂度 \(\color{blue}{\mathcal O(m+\log n)}\)

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    const int N = 250003, mod = 998244353;
    void qmo(int &x){x += x >> 31 & mod;}
    int ksm(int a, int b){
        int res = 1;
        for(;b;b >>= 1, a = (LL)a * a % mod)
            if(b & 1) res = (LL)res * a % mod;
        return res;
    }
    int n, m, pw[N], fac[N], inv[N], ans;
    int C(int n, int m){
        if(m < 0 || n < m) return 0;
        return (LL)fac[n] * inv[m] % mod * inv[n-m] % mod;
    }
    int main(){
        ios::sync_with_stdio(false);
        cin >> n >> m; *fac = *pw = 1;
        for(int i = 1;i < N;++ i) qmo(pw[i] = (pw[i-1]<<1) - mod);
        for(int i = 1;i < N;++ i) fac[i] = fac[i-1] * (pw[i] - 1ll) % mod;
        inv[N-1] = ksm(fac[N-1], mod-2);
        for(int i = N-1;i;-- i) inv[i-1] = inv[i] * (pw[i] - 1ll) % mod;
        for(int k = 1, tmp = 1;k <= n && k <= m;++ k){
            tmp = tmp * ((LL)pw[n]+mod-pw[k-1]) % mod;
            ans = (ans + ((pw[m+1]-1ll+mod-pw[m-k])*C(m,k)+mod-((LL)k*pw[k]+1)%mod*C(m,k+1)%mod) % mod * tmp) % mod;
        }
        if(ans & 1) ans += mod;
        printf("%d\n", ans >> 1);
    }
    
  • 相关阅读:
    收集Linux常用命令
    loadrunner没有告诉你的
    loadrunner没有告诉你的
    loadrunner没有告诉你的
    QA、EPG、PMO各自的职能划分及关系是什么?
    QA、EPG、PMO各自的职能划分及关系是什么?
    QA、EPG、PMO各自的职能划分及关系是什么?
    loadrunner通过odbc测mysql数据库语句
    loadrunner通过odbc测mysql数据库语句
    loadrunner通过odbc测mysql数据库语句
  • 原文地址:https://www.cnblogs.com/AThousandMoons/p/16204675.html
Copyright © 2020-2023  润新知