如 果 这 篇 文 章 有 帮 到 你 , 留 个 言 让 博 主 开 心 一 下 吧 \color{Orange}{如果这篇文章有帮到你,留个言让博主开心一下吧} 如果这篇文章有帮到你,留个言让博主开心一下吧~ 讲 的 可 能 不 是 很 好 讲的可能不是很好 讲的可能不是很好

− − − − − − − − − − − − − − − − − − − − − − 分 割 − − − − − − − − − − − − − − − − − − − − − − − − − \color{Red}{----------------------分割-------------------------} −−−−−−−−−−−−−−−−−−−−−−分割−−−−−−−−−−−−−−−−−−−−−−−−−

让 我 们 一 步 一 步 慢 慢 来 让我们一步一步慢慢来 让我们一步一步慢慢来

举 个 例 子 , 当 排 列 长 度 是 n 时 举个例子,当排列长度是n时 举个例子,当排列长度是n时

考 虑 x 和 y 作 为 某 对 [ l , r ] 中 的 最 大 值 和 最 小 值 , 有 多 少 排 列 包 含 这 对 ? 考虑x和y作为某对[l,r]中的最大值和最小值,有多少排列包含这对? 考虑x和y作为某对[l,r]中的最大值和最小值,有多少排列包含这对?

根 据 题 意 r − l = x − y , 区 间 长 度 为 L = x − y + 1 根据题意r-l=x-y,区间长度为L=x-y+1 根据题意r−l=x−y,区间长度为L=x−y+1

说 明 这 个 区 间 可 以 放 在 ( n − L + 1 ) 个 位 置 说明这个区间可以放在(n-L+1)个位置 说明这个区间可以放在(n−L+1)个位置

然 后 只 能 用 大 于 y 小 于 x 的 数 填 充 这 个 小 区 间 然后只能用大于y小于x的数填充这个小区间 然后只能用大于y小于x的数填充这个小区间

所 以 小 区 间 的 方 案 是 L ! , 其 他 地 方 数 可 以 随 便 放 ( n − L ) ! 所以小区间的方案是L!,其他地方数可以随便放(n-L)! 所以小区间的方案是L!,其他地方数可以随便放(n−L)!

所 以 , 以 x , y 作 为 小 区 间 中 的 m a x 和 m i n 时 所以,以x,y作为小区间中的max和min时 所以,以x,y作为小区间中的max和min时

有 ( n − L + 1 ) ∗ ( L ! ) ∗ ( n − L ) ! 个 排 列 满 足 要 求 有(n-L+1)*(L!)*(n-L)!个排列满足要求 有(n−L+1)∗(L!)∗(n−L)!个排列满足要求

于 是 我 们 枚 举 x 和 y 的 值 累 加 答 案 , 最 后 加 上 特 殊 的 区 间 长 度 为 1 的 情 况 就 是 答 案 于是我们枚举x和y的值累加答案,最后加上特殊的区间长度为1的情况就是答案 于是我们枚举x和y的值累加答案,最后加上特殊的区间长度为1的情况就是答案

如 果 你 还 没 有 看 懂 上 面 的 意 思 , 没 关 系 , 我 们 来 举 个 例 子 \color{Red}{如果你还没有看懂上面的意思,没关系,我们来举个例子} 如果你还没有看懂上面的意思,没关系,我们来举个例子

当 排 列 长 度 为 5 时 当排列长度为5时 当排列长度为5时

我 们 枚 举 x 和 y , 假 设 当 前 x = 4 , y = 1 我们枚举x和y,假设当前x=4,y=1 我们枚举x和y,假设当前x=4,y=1

所 以 区 间 长 度 时 是 4 , 那 么 这 个 区 间 可 以 放 在 [ 1 , 4 ] 和 [ 2 , 5 ] 两 个 地 方 所以区间长度时是4,那么这个区间可以放在[1,4]和[2,5]两个地方 所以区间长度时是4,那么这个区间可以放在[1,4]和[2,5]两个地方

而 且 这 个 区 间 一 定 是 由 1 , 2 , 3 , 4 填 充 , 有 4 ! 种 选 法 而且这个区间一定是由1,2,3,4填充,有4!种选法 而且这个区间一定是由1,2,3,4填充,有4!种选法

出 去 这 个 区 间 外 排 列 还 有 1 个 位 置 , 有 1 ! 种 选 法 出去这个区间外排列还有1个位置,有1!种选法 出去这个区间外排列还有1个位置,有1!种选法

所 以 x = 4 , y = 1 时 排 列 有 2 ∗ ( 4 ! ) ( 1 ! ) 种 选 法 所以x=4,y=1时排列有2*(4!)(1!)种选法 所以x=4,y=1时排列有2∗(4!)(1!)种选法

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int maxn=250009;
int n,mod,x,y,ans;
int fac[maxn];
signed main()
{
cin>>n>>mod;
fac[0]=1;
for(int i=1;i<=n;i++) fac[i]=fac[i-1]*i%mod;//求阶乘
for(int i=1;i<=n;i++)
for(int j=i+1;j<=n;j++)
{
int l=j-i+1;
int option=n-l+1;//区间选法
int yushu=n-l;//余下的数字随意排列
ans=(ans+option*fac[l]%mod*fac[n-l])%mod;
}
ans=(ans+fac[n]*n%mod)%mod;//加上区间长度为1的答案
cout<<ans;
}

遗 憾 的 时 , O ( n 2 ) 远 远 不 够 \color{Red}{遗憾的时,O(n^2)远远不够} 遗憾的时,O(n2)远远不够

但 是 我 们 突 然 发 现 x 和 y 的 值 并 不 重 要 但是我们突然发现x和y的值并不重要 但是我们突然发现x和y的值并不重要

比 如 ( 4 , 5 ) 和 ( 5 , 6 ) 的 对 数 是 一 样 的 比如(4,5)和(5,6)的对数是一样的 比如(4,5)和(5,6)的对数是一样的

所 以 接 下 来 我 们 只 枚 举 区 间 长 度 所以接下来我们只枚举区间长度 所以接下来我们只枚举区间长度

在 上 面 的 基 础 上 乘 以 区 间 长 度 为 i 时 的 选 法 在上面的基础上乘以区间长度为i时的选法 在上面的基础上乘以区间长度为i时的选法

比 如 区 间 长 度 为 2 时 可 以 选 ( 1 , 2 ) , ( 2 , 3 ) , ( 3 , 4 ) 等 等 比如区间长度为2时可以选(1,2),(2,3),(3,4)等等 比如区间长度为2时可以选(1,2),(2,3),(3,4)等等

那 就 乘 上 这 些 区 间 的 个 数 n − i + 1 那就乘上这些区间的个数n-i+1 那就乘上这些区间的个数n−i+1

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int maxn=250009;
int n,mod,x,y,ans;
int fac[maxn];
signed main()
{
cin>>n>>mod;
fac[0]=1;
for(int i=1;i<=n;i++) fac[i]=fac[i-1]*i%mod;//求阶乘
for(int i=1;i<=n;i++)//枚举区间长度
{
int option=n-i+1;//区间位置选法
int yushu=n-i;//剩下的数随便排列
int extra=n-i+1;//区间长度为i的有n-i+1种
ans=(ans+option*fac[i]%mod*fac[n-i]%mod*extra%mod)%mod;
}
cout<<ans;
}