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. 阿里云 EMAS Serverless 重磅发布

    简介: EMAS Serverless 是阿里云提供的基于Serverless技术的一站式后端开发平台,为开发者提供高可用.弹性伸缩的云开发服务,包含云函数.云数据库.云存储.静态网站托管等功能,可用 ...

  2. 双引擎驱动Quick BI十亿数据0.3秒分析,首屏展示时间缩短30%

    ​简介:在规划中,Quick BI制定了产品竞争力建设的三大方向,包括Quick(快)能力.移动端能力和集成能力.针对其中的产品"报表查看打开慢""报表开发数据同步慢&q ...

  3. 一文详解 | 开放搜索兼容Elasticsearch做召回引擎

    ​简介:开放搜索发布开源兼容版,支持阿里云Elasticsearch做搜索召回引擎,本文详细介绍阿里云ES用户如何通过接入开放搜索兼容版丰富行业分词库,提升查询语义理解能力,无需开发.算法投入,即可获 ...

  4. dotnet UNO 如何在调试下输出界面层级结构

    本文将告诉大家如何在 UNO 里面将界面的层级结构输出到调试窗口 实现方法非常简单,和 WPF 或 UWP 等的方法是一样的,那就是通过可视化树遍历的方式,如以下代码 static class UIS ...

  5. WPF 对接 Vortice 调用 D2D 使用 IWICBitmap 离屏渲染

    通过 Vortice 库可以使用非常底层的方式调用到 Direct2D1 进行渲染,本文将使用 D2D 离屏渲染到 IWICBitmap 上,再使用一点点反射黑科技,直接将此 IWICBitmap 对 ...

  6. 2019-11-29-WPF-Process.Start-出现-Win32Exception-异常

    title author date CreateTime categories WPF Process.Start 出现 Win32Exception 异常 lindexi 2019-11-29 10 ...

  7. net core下链路追踪skywalking安装和简单使用

    当我们用很多服务时,各个服务间的调用关系是怎么样的?各个服务单调用的顺序\时间性能怎么样?服务出错了,到底是哪个服务引起的?这些问题我们用什么方案解决呢,以前的方式是各个系统自己单独做日志,出了问题从 ...

  8. Mybatis的逆向工程(generator)

    Tips:Mybatis generator官网 http://www.mybatis.org/generator/configreference/commentGenerator.html Myba ...

  9. 【GUI界面软件】抖音评论采集:自动采集10000多条,含二级评论、展开评论!

    目录 一.背景说明 1.1 效果演示 1.2 演示视频 1.3 软件说明 二.代码讲解 2.1 爬虫采集模块 2.2 软件界面模块 2.3 日志模块 三.获取源码及软件 一.背景说明 1.1 效果演示 ...

  10. 【图形数据集】CIFAR-10 dataset数据集

    文献引用:https://www.cs.toronto.edu/~kriz/cifar.html The CIFAR-10 dataset The CIFAR-10 dataset consists ...