USACO 19JAN Train Tracking 2 P 题解

题目传送门

题目大意: 有一个长度为 n n n 的序列 a a a,有一个 k k k,给出每个长度为 k k k 的子段的最小值,问这个序列有多少种可能性。

题解

容易发现假如 c i − 1 > c i c_{i-1}>c_i ci1>ci,那么就可以确定 a i + k − 1 = c i a_{i+k-1}=c_i ai+k1=ci

所以需要考虑的是一段相同的 c i c_i ci 要如何处理,即考虑一个子问题:当所有 c i c_i ci 相等时,这个序列有多少种可能性?

f i f_i fi 表示长度为 i i i 的序列的方案数,令 d = c 1 = c 2 = . . . = c n − k + 1 , p = 1 0 9 − d d=c_1=c_2=...=c_{n-k+1},p=10^9-d d=c1=c2=...=cnk+1,p=109d,由于每 k k k 位至少有一个数恰好为 c i c_i ci,可以得到这样的 dp \text{dp} dp 方程:
f i = ( p + 1 ) f i − 1 − p k f i − k − 1 f_i=(p+1)f_{i-1}-p^kf_{i-k-1} fi=(p+1)fi1pkfik1

( p + 1 ) f i − 1 (p+1)f_{i-1} (p+1)fi1 表示第 i i i 位随便放,然后去掉不合法的方案,即后 k k k 个都大于 d d d 的方案,由于序列前 i − 1 i-1 i1 位是合法的,所以当后 k k k 个都大于 d d d 时,第 i − k i-k ik 个一定为 d d d,所以方案数为 f i − k − 1 f_{i-k-1} fik1

当考虑一段相等的 c [ l , r ] c_{[l,r]} c[l,r] 时,假如相邻的 c c c 比它大,比如 c l − 1 > c l c_{l-1}>c_l cl1>cl,那么 a [ l − 1 , l + k − 2 ] a_{[l-1,l+k-2]} a[l1,l+k2] 这一段已经被前面的 c c c 考虑了,而 c l + k − 1 c_{l+k-1} cl+k1 一定为 c l c_l cl,也不需要考虑,所以需要 d p dp dp 的部分就少了 k k k 个,去掉他们再 d p dp dp 即可。

代码如下:

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define maxn 100010
#define mod 1000000007

int n,k,a[maxn],ans=1;
int f[maxn];
int ksm(int x,int y){int re=1;for(;(y&1?re=1ll*re*x%mod:0),y;y>>=1,x=1ll*x*x%mod);return re;}
int dp(int ln,int mi){
	int p=1e9-mi,p_=ksm(p,k);f[0]=1;
	for(int i=1;i<=ln;i++){
		f[i]=1ll*f[i-1]*(p+1)%mod;
		if(i>=k)f[i]=(f[i]-1ll*p_*(i>k?f[i-k-1]:1)%mod+mod)%mod;
	}
	return f[ln];
}

int main()
{
	scanf("%d %d",&n,&k);
	for(int i=1;i<=n-k+1;i++)scanf("%d",&a[i]);
	for(int i=1;i<=n-k+1;i++){
		int j=i;while(a[j+1]==a[i])j++;
		int len=j-i+k;
		if(i>1&&a[i-1]>a[i])len-=k;
		if(j<n-k+1&&a[j+1]>a[j])len-=k;
		if(len>0)ans=1ll*ans*dp(len,a[i])%mod;
		i=j;
	}
	printf("%d",ans);
}
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 、4下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合;、下载 4使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合;、 4下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值