首页 > 其他分享 >[ABC134F] Permutation Oddness 题解

[ABC134F] Permutation Oddness 题解

时间:2023-08-15 19:22:32浏览次数:42  
标签:Oddness 题解 元素 T1 MOD 配对 ABC134F 2j mod

题面

定义一个 \(1 \sim n\) 的排列 \(p\) 的「怪异度」为

\[\sum_{i=1}^n\left\lvert p_i-i\right\rvert \]

求「怪异度」为 \(k\) 的 \(1 \sim n\) 的排列数,答案对 \(10^9+7\) 取模。

题解

考虑转化计算怪异度的过程,我们将值 \(p_i\) 排列在左侧,将下标 \(i\) 排列在右侧,构成一个 \(n \times 2\) 的矩阵。将值和下标一一配对,定义配对一对元素的贡献为 \(\left\lvert p_i-i\right\rvert\),求使总贡献为 \(m\) 的配对方案。注意,这里的配对要求必须是值和下标配对,换句话说就是这个矩阵不同列的元素配对。

定义 \(f_{i, j, k}\) 为前 \(i\) 行中有 \(j\) 对元素没有进行配对的情况下总贡献为 \(k\) 的方案数。

发现 \(k\) 的定义不便于维护,考虑转化总贡献的计算方法。在矩阵的每两行之间插入一个计数器,计数器的贡献值为经过这个计数器的配对的数量,可以看出配对的总贡献就是所有计数器的贡献和。发现当前计数器的贡献即前 \(i\) 行未配对元素的数量,证明可以考虑在前 \(i\) 行没有配对的元素一定会和第 \(i + 1 \sim n\) 行的元素配对,那么一定会经过矩阵第 \(i\) 行和第 \(i + 1\) 行之间的计数器并产生贡献,故可以进行转移。

\(f\) 的转移可以考虑在当前矩阵的基础上新增了一行,考虑这一行会产生几个配对,不难发现这一行两个元素可以产生的配对数量为 \(0, 1, 2\),考虑枚举这三种情况进行转移。

配对 \(0\) 对

在前 \(i\) 行有 \(j\) 对没有进行配对且第 \(i\) 行的两个元素均为配对,所以该状态可以从 \(f_{i - 1, j - 1, k - 2j}\) 转移。

配对 \(1\) 对

考虑两种情况:

  1. 第 \(i\) 行的元素与前 \(i - 1\) 行未配对的元素进行配对,单个元素的方案为 \(j\),因为有两个元素,所以这部分的方案为 \(2j\);

  2. 第 \(i\) 行的两个元素进行配对,方案数为 \(1\)。

因为第 \(i\) 行的元素不会产生新的未配对数量,所以这两种情况均从 \(f_{i - 1, j, k - 2j}\) 中转移而来。

配对 \(2\) 对

考虑前 \(i - 1\) 行有多少对元素未配对,因为第 \(i\) 行的两个元素均与前 \(i - 1\) 行的元素进行了配对,所以消除了前 \(i - 1\) 行的一对未配对元素,因而前 \(i - 1\) 行有 \(j + 1\) 对未配对元素,故该状态从 \(f_{i - 1, j + 1, k - 2j}\) 转移。

对于第 \(i\) 行的每个元素,均可以与另一列前 \(i - 1\) 行的 \(j + 1\) 个未配对元素进行独立配对,故方案数为 \(\left(j + 1\right)^2\)。

根据加法原理,可以得到总的转移式

\[f_{i, j, k} = f_{i - 1, j - 1, k - 2j} + (2j + 1) \times f_{i - 1, j, k - 2j} + \left(j + 1\right)^2 \times f_{i - 1, j + 1, k - 2j} \]

初始状态为 \(f_{0, 0, 0} = 1\),根据该转移式递推即可以 \(\mathcal{O}(n^4)\) 的复杂度通过本题。

Code

#include <bits/stdc++.h>

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

constexpr valueType MAXN = 55;

constexpr valueType MOD = 1e9 + 7;

bool ModOperSafeModOption = true;

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

        if (a < 0)
            a += MOD;

        if (b < 0)
            b += 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) {
    if (ModOperSafeModOption) {
        a %= MOD;
        b %= MOD;

        if (a < 0)
            a += MOD;

        if (b < 0)
            b += 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) {
    if (ModOperSafeModOption) {
        a %= MOD;
        b %= MOD;

        if (a < 0)
            a += MOD;

        if (b < 0)
            b += 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) {
    if (ModOperSafeModOption) {
        a %= MOD;
        b %= MOD;

        if (a < 0)
            a += MOD;

        if (b < 0)
            b += 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) {
    if (ModOperSafeModOption) {
        a %= MOD;
        b %= MOD;

        if (a < 0)
            a += MOD;

        if (b < 0)
            b += 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) {
    if (ModOperSafeModOption) {
        a %= MOD;
        b %= MOD;

        if (a < 0)
            a += MOD;

        if (b < 0)
            b += 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) {
    if (ModOperSafeModOption) {
        a %= MOD;
        b %= MOD - 1;

        if (a < 0)
            a += MOD;

        if (b < 0)
            b += MOD - 1;
    }

    T1 result = 1;

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

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

    return result;
}

std::array<std::array<std::array<valueType, MAXN * MAXN>, MAXN>, MAXN> dp;

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

    valueType N, M;

    std::cin >> N >> M;

    if (M & 1) {
        std::cout << 0 << std::endl;

        return 0;
    }

    dp[0][0][0] = 1;

    for (valueType i = 1; i <= N; ++i) {
        for (valueType j = 0; j <= i; ++j) {
            for (valueType k = 2 * j; k <= M; k += 2) {
                dp[i][j][k] = 0;

                Inc(dp[i][j][k], mul((j + 1) * (j + 1), dp[i - 1][j + 1][k - 2 * j]));

                Inc(dp[i][j][k], mul(2 * j + 1, dp[i - 1][j][k - 2 * j]));

                if (j >= 1) {
                    Inc(dp[i][j][k], dp[i - 1][j - 1][k - 2 * j]);
                }
            }
        }
    }

    std::cout << dp[N][0][M] << std::endl;

    return 0;
}

标签:Oddness,题解,元素,T1,MOD,配对,ABC134F,2j,mod
From: https://www.cnblogs.com/User-Unauthorized/p/solution-AT-ABC134-F.html

相关文章

  • [ABC134F] Permutation Oddness
    题目大意定义一个\(1\simn\)的排列\(p\)的「怪异度」为\[\sum_{i=1}^n|p_i-i|\]求「怪异度」为\(m\)的\(1\simn\)的排列数,答案对\(10^9+7\)取模。思路考虑把\(p_i\)和\(i\)看作小球与盒子,方便题意理解。考虑球与盒子的匹配。假设球在左侧,盒子在右侧,他们......
  • 『题解』ABC261Ex Game on Graph
    题目链接震惊!这个题竟然被神犇szs放进了博弈论里!我真的没看出来除了题面还有哪里像博弈论(也许是因为我菜)。转移方式很显然,按照题面说的做就行了。那么正解也就呼之欲出了。但是我知道大家都会正解,就是魔改的堆优化Dijkstra,所以我想说的是一种歪解,以及它是歪解的原因。歪解......
  • 国标GB28181视频平台EasyGBS国标平台设备播放断流现象的问题解决方案
    安防视频监控EasyGBS平台基于国标GB28181协议,支持多路设备接入,并对多平台、多终端分发出RTSP、RTMP、FLV、HLS、WebRTC等多种格式的视频流。平台可为大数据等综合性监管平台提供极强的视频能力,已经在大量的项目中落地应用,如明厨亮灶、平安乡村、雪亮工程等。有用户反馈,在安防视频监......
  • 视频汇聚平台EasyCVR安防监控视频汇聚平台的FLV视频流在VLC中无法播放的问题解决方案
    众所周知,TSINGSEE青犀视频汇聚平台EasyCVR可支持多协议方式接入,包括主流标准协议国标GB28181、RTSP/Onvif、RTMP等,以及厂家私有协议与SDK接入,包括海康Ehome、海大宇等设备的SDK等。在视频流的处理与分发上,视频监控汇聚平台EasyCVR的性能也同样表现得很优秀,平台可对外分发多格式的视......
  • [Luogu P8716] 回文日期 题解
    STEP1:分析题目大意:给定一个8位数的日期,请你计算该日期之后下一个回文日期和下一个ABABBABA型的回文日期各是哪一天。这一题一眼看出是P2010的升级版,所以要先考虑到超时问题,因为如果一天一天地枚举,时间复杂度会非常高,所以我们不能直接枚举。因为题目只要"回文",所以我们只......
  • [JOI 2023 Final] Advertisement 2 题解
    题解JOI王国有\(N\)位居民,从\(1\)到\(N\)编号。居民\(i\)(\(1\lei\leN\))居住在数轴上坐标\(X_i\)处,其影响力为\(E_i\)。同一个坐标可能住了多于一位居民。居民的影响力越高,广告效应也越高,但买书也越谨慎。Rie出版了一本关于信息学的书。为了让更多人购买这本书,她可......
  • 【免费分享 图书】《阿里云天池大赛赛题解析——深度学习篇》-PDF电子书-百度云
    找这本书的资源简直要把我找吐了,各种网站压缩包一下下来就开始各种套路(比如要你充钱)为了防止还有我这样的受害者,这就把找到的PDF给大家分享一下。链接在文章最后如果这篇文章能够帮到您,麻烦帮我点个赞,并关注一下我,我将有更多动力,持续分享更多有用图书给您!非常感谢,不胜感激!(点......
  • P3629 巡逻 LCA题解
    原题:洛谷P3629问题转化首先,给定的图是一个有\(n\)个点,\(n-1\)条边的无向连通图,这个图就等价于一棵树。不建立新的道路时,从\(1\)号节点出发,把整棵树上的每条边遍历至少一次,再回到\(1\)号节点,会恰好经过每条边两次,路线总长度为\(2(n-1)\),如下图最左边的部分所示。根据树......
  • SVN 不显示红绿图标问题解决方案
    本地文件夹我们先在桌面或者资源管理器中鼠标右键打开设置  选择IconOverlays(图标覆盖) Status cache(状态缓存)选择‘Shell’ 接着选择IconOverlays(图标覆盖)下的IconSet(图标集)  选择应用然后确认,重启生效     ssh等方式挂载的远程磁盘......
  • 2019考研英语(一)小作文真题解析与参考 Aiding Rural Primary Schools 答复信
    2019考研英语(一)小作文真题解析与参考Directions:Supposeyouareworkingforthe“AidingRuralPrimarySchools” projectofyouruniversity.Writeanemailtoanswertheinquiryfromaninternationalschoolvolunteer,specifyingthedetailsoftheproject.Yous......