P7322

好神仙!

\(\color{#5bc9}\text{提醒,本文有大量没有推到过程的式子,所以读者可以自己遮住先推一下}\)

Inscription:

有一个长度为 \(k\) 的窗口,在一个长度为 \(n\) 的序列 \(a\) 上滑动,请问滑动窗口中的数的 \(\min\) 共有多少种值。

Solution:

接下来我们考虑之后什么情况才会让答案 \(+1\)。

既然每次向右移动 \(1\) 的长度,那么只有可能删除的数或者新加入的数是最小值答案才有可能 \(+1\)。

对于最左边的数是窗口滑动之前是窗口最小值,进行一波推式子之后(此处省略一万行),可以发现它对答案的贡献有:

\[s1=\sum^{n-k}_{i = 1}C^{k-1}_{n-i} \times (n-k)! \times (k-1)! \times (n-k)
\]

解释一下:

其中从左往右,求和符合是枚举这个最小值的大小,组合数是令窗口中剩余的 \(k−1\) 个数大于最小值的值的个数。

两个阶乘分别是窗口外面的数任意排列和窗口内部除去最小值外任意排列。

最后一个 \(n−k\) 是计算排列中窗口可以在的位置有 \(n−k\) 个。

同理新加入的数的的贡献就为:

\[s2=\sum^{n-k}_{i = 1} C^{k}_{n-i} \times (n-k-1)! \times k! \times (n-k)
\]

但是未免有左右两边都是最小的情况,所以我们要减去。

所以需要减掉的部分为:

\[s3=\sum^{n-k}_{i = 1}C^{k-1}_{n-i} \times (n - k - 1)! \times (k - 1)! \times (n-k) \times (i-1)
\]

\(i−1\) 是最右边小于最左边的个数。

\(\color{violet} \text{注意:最后还需要加上每个排列都缺少的 1 答案,也就是总答案加上 n!}\)。

但是我不甘于 \(O(n-k)\) 的做法(除了预处理),于是就有了下面的事情。

我们来化简 \(s1,s2,s3\)(化简过程略,读者可以自己遮住先推一下)。

\[s1 = \sum^{n-k}_{i=1} \dfrac{n-k}{(n-k-i+1)!} \times (n-k)! \times (n-i)!
\]
\[s2 = \sum^{n-k}_{i=1} \dfrac{1}{(n-k-i)!} \times (n-k)! \times (n-i)!
\]
\[s3 = \sum^{n-k}_{i=1} \dfrac{i-1}{(n-k-i+1)!} \times (n-k)! \times (n-i)!
\]

然后呢,就有一个规律,那就是 \(s1 - s3 = s2\)。

所以答案从 \(s1 + s2 - s3 + n!\) 变成了 \(2 \times s2 + n!\)。

但是,我们还不满足。

\(s2\) 仍然可以化简(读者可以自己遮住先推一下)。

\[s2 = \dfrac{(n+1)!}{k+1} - n!
\]

所以把上面这个式子带入求答案的式子。

所以:

\[\dfrac{2 \times (n+1)!}{k+1} - n!
\]

所以完结撒花!!

最后贴上代码:

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int mod = 998244353;
int qpow(int a,int b)
{
int res = 1;
while(b)
{
if(b & 1)
{
res = res * a % mod;
}
b >>= 1;
a = a * a % mod;
}
return res;
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
int n,k;
cin >> n >> k;
int fac = 1;
for(int i = 1;i <= n;i++)
{
fac = fac * i % mod;
}
cout << (2 * (fac * (n + 1) % mod) * qpow(k + 1,mod - 2) % mod - fac + mod) % mod;
return 0;
}

随机推荐

  1. 【笔记】go语言--(Slice)切片的概念

    go--(Slice)切片的概念 //切片是什么,定义一个arr,定义一个s为arr中的2到6,这个s就是一个切片 arr := [...]int{0,1,2,3,4,5,6,7} s := arr[ ...

  2. Hexo博客框架—轻量、一令部署

    ​简介:Hexo 是一个快速.简洁且高效的博客框架.Hexo 使用 Markdown(或其他渲染引擎)解析文章,在几秒内,即可利用靓丽的主题生成静态网页.Hexo支持Github Flavored M ...

  3. OpenTelemetry 简析

    简介: OpenTelemetry 是 CNCF 的一个可观测性项目,旨在提供可观测性领域的标准化方案,解决观测数据的数据模型.采集.处理.导出等的标准化问题,提供与三方 vendor 无关的服务. ...

  4. MaxCompute跨境访问加速解决方案

    简介: MaxCompute联合全球加速服务,为有跨境访问需求的MaxCompute客户提供一套高效稳定的跨境访问加速方案. MaxCompute联合全球加速服务,为有跨境访问需求的MaxComput ...

  5. [Go] 选择 Beego 的三个理由

    1. 项目支持角度较其它框架考虑的多一些,比如:目录结构的简单约定,内置项目配置读取,内置bee脚手架,热重载特性 等. (实际这些 feature 都可以找到 golang 专精的组件引入起来,效果 ...

  6. Stable Diffusion中的embedding

    Stable Diffusion中的embedding 嵌入,也称为文本反转,是在 Stable Diffusion 中控制图像样式的另一种方法.在这篇文章中,我们将学习什么是嵌入,在哪里可以找到它们 ...

  7. 习题8 #第8章 Verilog有限状态机设计-3 #Verilog #Quartus #modelsim

    3. 编写一个8路彩灯控制程序,要求彩灯有以下3种演示花型. (1) 8路彩灯同时亮灭: (2) 从左至右逐个亮(每次只有1路亮): (3) 8路彩灯每次4路灯亮,4路灯灭,且亮灭相间,交替亮灭. 在 ...

  8. MacBook M1 虚拟机安装Windows for ARM使用体验

    前言 大家好,我是 刚进入春天还没来得及踏青又开始从早忙到晚的 蛮三刀.去年给大家带来了一篇比较详尽的MacBook M1评测.评测经历了全网的热情转载,成为了我唯一的一篇爆款文章(我该哭还是该笑!) ...

  9. 五、Doris数据分布

    在 Doris 中,数据都以表(Table)的形式进行逻辑上的描述 名词解释 数据分布:数据分布是将数据划分为子集, 按一定规则, 均衡地分布在不同节点上,以期最大限度地利用集群的并发性能 短查询:s ...

  10. 在英特尔至强 CPU 上使用 🤗 Optimum Intel 实现超快 SetFit 推理

    在缺少标注数据场景,SetFit 是解决的建模问题的一个有前途的解决方案,其由 Hugging Face 与 Intel 实验室 以及 UKP Lab 合作共同开发.作为一个高效的框架,SetFit ...