首页 > 其他分享 >[ARC104F] Visibility Sequence 题解

[ARC104F] Visibility Sequence 题解

时间:2023-11-03 20:56:30浏览次数:34  
标签:right const ARC104F 题解 Visibility T1 left 节点 mod

题意

对于一个长度为 \(N\) 的序列 \(H\),可以通过如下方式构造一个序列 \(P\):

若存在 \(j \in \left[1, i\right)\),使得 \(H_j > H_i\),则 \(P_i = \max\limits_{j \in \left[1, i\right) \land H_j > H_i} j\),否则 \(P_i = -1\)。

给定一个长度为 \(N\) 的序列 \(X\),求所有满足如下条件的 \(H\) 序列可以构造出的 \(P\) 序列的方案数:

\(\forall i \in \left[1, N\right], H_i \in \left[1, X_i\right]\)

对 \(10^9 + 7\) 取模。

\(1 \le N \le 100, 1 \le X_i \le 10^5\)。

题解

考虑从 \(i\) 向 \(P_i\) 连边,发现会连成一个森林,考虑将 \(H_0\) 设为 \(+\infty\),这样就可以形成一颗以 \(0\) 为根的树。可以发现其一定有如下性质:

  1. 对于任意节点 \(u\),有 \(\forall v \in \operatorname{subtree}_u \Rightarrow H_u > H_v\)

证明:
对于任意节点 \(x\),有 \(H_{fa_x} > H_{x}\),通过不等式的传递性可证。

  1. 一定存在一种 \(\tt{DFS}\) 方式使得 \(\forall i \in \left[1, N\right]\),有 \(\operatorname{dfn}(i) = i\)

证明:
考虑 \(\tt{DFS}\) 到节点 \(u\) 后,下一个访问的节点是否可以是 \(u + 1\)。

  • 若 \(H_u > H_{u + 1}\),那么 \(u\) 和 \(u + 1\) 之间一定有边相连;
  • 否则对于任意 \(i > u + 1\),其不会向 \(u\) 连边,所以在 \(\tt{DFS}\) 过程中,不会访问其他节点。
  1. 对于节点 \(u\) 的儿子节点序列 $v_1 < v_2 < \cdots v_k $,有 \(\forall i \in \left[1, k\right], H_{v_i} \le H_{v_{i + 1}}\)

证明:
考虑若存在 \(i < j\),使得 \(H_{v_i} > H_{v_j}\),那么 \(v_i\) 和 \(v_j\) 之间一定有边相连,矛盾。

  1. 对于节点 \(u\) 的儿子节点序列 $v_1 < v_2 < \cdots v_k $,有 \(\forall i \in \left[1, k\right], H_{v_i} < H_u\)

证明:
考虑若存在 \(i\),使得 \(H_{v_i} \ge H_u\),那么 \(v_i\) 和 \(u\) 之间一定没有边相连,矛盾。

至此我们可以得出对于一个节点 \(u\),有 \(H_u \ge \max\left\{\max\limits_{v \in \operatorname{son}_u}H_v + 1,\max\limits_{v \in \operatorname{brother}_u \land v < u}H_v\right\}\)。

考虑如何在给定 \(P\) 序列即树的形态的情况下构造出一组合法的 \(H\) 或报告无解。发现从叶子节点向上构造并直接将 \(H_u\) 的值取至下界一定不劣,因此我们就得出了一个基于贪心的构造方法。

同时我们可以发现按此方法构造出的 \(H\) 序列其值不超过 \(N\),因此若 \(X_i > N\) 那么使其对 \(N\) 取 \(\min\) 即可。

考虑按此方法进行 \(\tt{DP}\),设 \(f_{l, r, x}\) 表示由编号区间 \(\left[l, r\right]\) 中的点构成的树且 \(l\) 节点作为根节点有 \(H_l = x\) 的方案数,\(g_{l, r, x}\) 表示由编号区间 \(\left[l, r\right]\) 中的点构成的森林且对于编号最大的根节点 \(u\) 有 \(H_u = x\) 的方案数。

初始状态为 \(\forall i \in \left[1, N\right], f_{i, i, 1} = 1\)。

接下来考虑如何转移,首先我们有

\[f_{l, r, x} = g_{l + 1, r, x - 1} \]

然后考虑 \(g_{l, r, x}\) 的转移,我们可以枚举其最后一棵子树的编号区间和根节点权值,有

\[g_{l, r, x} = \sum\limits_{m = l}^{r - 1}\sum\limits_{\max\limits\left\{a, b\right\} = x} g_{l, m, a} \times f_{m + 1, r, b} \]

考虑若 \(b = x\),那么使得枚举的子树作为其最右侧的子树即可;反之则有 \(a = x\),使得枚举的子树并入其最右侧的子树即可。

最后答案即为 \(\sum\limits_{i = 1}^{N}g_{1, N, i}\)。

使用前缀和优化转移即可做到 \(\mathcal{O}(N^4)\) 的时间复杂度,可以通过本题。

Code

#include <bits/stdc++.h>

typedef long long valueType;
typedef std::vector<valueType> ValueVector;
typedef std::vector<ValueVector> ValueMatrix;
typedef std::vector<ValueMatrix> ValueCube;

namespace MODINT {
    constexpr valueType MOD = 1e9 + 7;

    template<typename T1, typename T2, typename T3 = valueType>
    void Inc(T1 &a, T2 b, const T3 &mod = MOD) {
        a = a + b;

        if (a >= mod)
            a -= mod;
    }

    template<typename T1, typename T2, typename T3 = valueType>
    void Dec(T1 &a, T2 b, const T3 &mod = MOD) {
        a = a - b;

        if (a < 0)
            a += mod;
    }

    template<typename T1, typename T2, typename T3 = valueType>
    T1 sum(T1 a, T2 b, const T3 &mod = MOD) {
        return a + b >= mod ? a + b - mod : a + b;
    }

    template<typename T1, typename T2, typename T3 = valueType>
    T1 sub(T1 a, T2 b, const T3 &mod = MOD) {
        return a - b < 0 ? a - b + mod : a - b;
    }

    template<typename T1, typename T2, typename T3 = valueType>
    T1 mul(T1 a, T2 b, const T3 &mod = MOD) {
        return (long long) a * b % mod;
    }

    template<typename T1, typename T2, typename T3 = valueType>
    void Mul(T1 &a, T2 b, const T3 &mod = MOD) {
        a = (long long) a * b % mod;
    }

    template<typename T1, typename T2, typename T3 = valueType>
    T1 pow(T1 a, T2 b, const T3 &mod = MOD) {
        T1 result = 1;

        while (b > 0) {
            if (b & 1)
                Mul(result, a, mod);

            Mul(a, a, mod);
            b = b >> 1;
        }

        return result;
    }
}// namespace MODINT

using namespace MODINT;

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    std::cout.tie(nullptr);

    valueType N;

    std::cin >> N;

    ValueVector H(N + 1);

    for (valueType i = 1; i <= N; ++i) {
        std::cin >> H[i];

        H[i] = std::min(H[i], N);
    }

    auto ModSum = [](valueType const &a, valueType const &b) -> valueType {
        return sum(a, b, MOD);
    };

    ValueCube F(N + 1, ValueMatrix(N + 1, ValueVector(N + 1, 0)));
    ValueCube G(N + 1, ValueMatrix(N + 1, ValueVector(N + 1, 0)));
    ValueCube SumF(N + 1, ValueMatrix(N + 1, ValueVector(N + 1, 0)));
    ValueCube SumG(N + 1, ValueMatrix(N + 1, ValueVector(N + 1, 0)));

    for (valueType i = 1; i <= N; ++i) {
        F[i][i][1] = 1;
        G[i][i][1] = 1;

        std::partial_sum(F[i][i].begin(), F[i][i].end(), SumF[i][i].begin(), ModSum);
        std::partial_sum(G[i][i].begin(), G[i][i].end(), SumG[i][i].begin(), ModSum);
    }

    for (valueType len = 1; len <= N; ++len) {
        for (valueType l = 1; l + len <= N; ++l) {
            valueType const r = l + len;

            for (valueType k = 1; k <= H[l]; ++k) {
                F[l][r][k] = G[l + 1][r][k - 1];
                G[l][r][k] = G[l + 1][r][k - 1];
            }

            for (valueType mid = l; mid < r; ++mid) {
                for (valueType k = 1; k <= H[mid + 1]; ++k) {
                    Inc(G[l][r][k], mul(G[l][mid][k], SumF[mid + 1][r][k - 1]));
                    Inc(G[l][r][k], mul(SumG[l][mid][k - 1], F[mid + 1][r][k]));
                    Inc(G[l][r][k], mul(G[l][mid][k], F[mid + 1][r][k]));
                }
            }

            std::partial_sum(F[l][r].begin(), F[l][r].end(), SumF[l][r].begin(), ModSum);
            std::partial_sum(G[l][r].begin(), G[l][r].end(), SumG[l][r].begin(), ModSum);
        }
    }

    std::cout << SumG[1][N][N] << std::endl;

    return 0;
}

标签:right,const,ARC104F,题解,Visibility,T1,left,节点,mod
From: https://www.cnblogs.com/User-Unauthorized/p/solution-ARC104F.html

相关文章

  • CF1866M Mighty Rock Tower 题解
    Problem-1866M-CodeforcesMightyRockTower-洛谷先考虑一个\(O(n^2)\)的dp设计状态:\(dp_i\)表示搭\(i\)层的期望转移:\(dp_i=dp_{i-1}\times(1-P_i)+\sum\limits_{j=i}^{n-1}dp_j\timesP_{j+1}^{j-i+1}\times(1-P_{j+1})\),显然是有后效性的,但我们展开......
  • [ARC104E] Random LIS 题解
    题意给定一个长度为\(N\)的序列\(A\),按照下列方式生成一个长度为\(N\)的序列\(X\):\(\foralli\in[1,n]\),\(X_i\)在\([1,A_i]\)中的整数中均匀随机生成。求其最长上升子序列长度的期望,对\(10^9+7\)取模。\(1\leN\le6,1\leA_i\le10^9\)。题解由于\(N\)......
  • CSP-S2023 全场题解
    lock这题就是个模拟吧,赛时被迷惑了以为是什么不可做题,仔细看只有\(10^5\)种状态,那就枚举好了。我们分别从状态串出发,枚举它能达到的答案,加到set取个并集,不过注意给定的状态不能是密码,要减掉。注意不要直接计数器减减,不然如果有相同的算在状态里面的会多减,我考场代码就这么被......
  • NOIP 提高组 题解
    NOIST2023涂色游戏对于每一行每一列记录一个时间戳,对于每个格子颜色即为时间戳较大的颜色。幂次考虑暴力,我们发现\(O(\sqrt[3]{n})\)的复杂度是可以接受的,所以可以枚举\(\sqrt[3]{n}\)内的数然后暴力往上乘,可以用一个unordered_map判重,时间复杂度大概为\(O(\sqrt[3]{n}......
  • 【POJ 1731】Orders 题解(全排列)
    描述商店经理按照标签的字母顺序对各种商品进行了分类。所有标签以同一字母开头的种类都存放在标有该字母的同一仓库(即在同一建筑物内)。在白天,商店经理接收并预订要从商店发货的货物订单。每个订单只需要一种货物。商店经理按照预订的顺序处理请求。你事先知道今天商店经理必须处......
  • flask部署在腾讯云上,但在本地使用网页无法访问——问题解决
    flask部署在腾讯云上,但在本地使用网页无法访问——问题解决1.修改腾讯云防火墙,把对应的port开放:2.修改代码if__name__=='__main__':app.run(host="0.0.0.0",port=5000,debug=True)参考链接:https://zhuanlan.zhihu.com/p/611969276......
  • HCIP Datacom H12-831考题解析
    OSPFv3专题6.关于0SPFv3报文,以下哪个描述是正确的?郑锦程校对整理2023.11.03A.OSPFv3的Hello报文携带了路由器所有接口的IPv6地址B.OSPFv3使用链路本地地址作为发送报文的源地址,报文可以被转发到始发链路范围之外C.OSPFv3使用IPv6组播地址FF02:1和FF02:2发送OSPFv3报文D.可以在OSPFv......
  • 【真题解析】软件工程-重点题目解析(1)
    截止2023年4月本系列是我自己在学习过程中记录的资料;因为内容比较格式比较多样;用markdown靠记录非常浪费时间;再加上对时效性的考虑;就以PPT的形式记录了;本系列因为是自己的理解为主,因此,难免与教材中的内容有误差,主要是从自己的知识角度解释题目的答案,个人感觉是有助于记忆的。如果有......
  • 苏格拉底问答、实践过程截图、遇到问题解决问题截图,代码链接
    #include<signal.h>#include<stdio.h>#include<sys/time.h>intcount=0;structitimervalt;voidtimer_handler(intsig){printf("timer_handler:signal=%dcount=%d\n",sig,++count);if(count>=8){printf("cancel......
  • [ARC104B] DNA Sequence 题解
    题意对于一个只含有A,C,T,G的字符串\(s\),定义其为匹配的当且仅当其中A的数量和T的数量相等,C的数量和G的数量相等。给定一个长度为\(N\)的字符串\(S\),求其有多少个非空子串是匹配的。\(1\leN\le5000\)。题解\(\mathcal{O}(N)\)做法。首先考虑如果字符集只有......