Loading

[HNOI2013]数列

portal

Solution

发现 \(a_1\) 的取值并不固定,所以考虑差分序列,这样就不用考虑 \(a_1\) 了。

由于相邻两天的差不超过 \(m\),也就是差分序列上的元素不超过 \(m\)。并且有 \(k\) 天,那么这个序列的元素个数是 \(k-1\)

我们考虑对于一个差分序列 \(S\),如果其中的元素已经确定,那么最终的答案个数是 \(n-\sum\limits_{i=1}^{k-1} S_i\)。也就是 \(a_1\) 的取值个数。

然后观察题目 \(m\times (k-1)<n\),也就是说就算每天都增长 \(m\) 最后也至少有一个 \(a_1\) 的取值是满足的。所以可以简单认为,\(S\) 的方案数就是 \(m^{k-1}\)

接下来我们设 \(S_i\) 为第 \(i\) 种差分序列,那么答案就是:

\[\sum_{i=1}^{m^{k-1}}(n-\sum_{j=1}^{k-1} S_{i,j}) \]

\[=m^{k-1}\times n-\sum_{i=1}^{m^{k-1}}\sum_{j=1}^{k-1} S_{i,j} \]

然后我们考虑求后面那一坨的东西。

直接做大概会 GG,所以考虑其意义。其实就是对于差分序列上的每个位置,所有取值的和。容易得到,对于一个位置上的一个值,总共出现了 \(m^{k-2}\) 次。也就是说:

\[\sum_{i=1}^{m^{k-1}}\sum_{j=1}^{k-1} S_{i,j}=m^{k-2}\times (k-1)\times \sum_{i=1}^mi=m^{k-2}\times (k-1)\times \dfrac{m\times (m+1)}{2} \]

然后就做完了。

Code

// Problem: P3228 [HNOI2013]数列
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P3228
// Memory Limit: 125 MB
// Time Limit: 1000 ms
// Author: ZCETHAN
// Time: 2021-11-10 13:59:12

#include<bits/stdc++.h>
#define ll long long
#define inf (1<<30)
#define INF (1ll<<60)
using namespace std;
ll MOD;
ll ksm(ll a,ll p){
	ll ret=1;while(p){
		if(p&1) ret=ret*a%MOD;
		a=a*a%MOD; p>>=1;
	}return ret;
}
int main()
{
	ll n,k,m;
	scanf("%lld%lld%lld%lld",&n,&k,&m,&MOD);
	n%=MOD;m%=MOD;
	ll x=ksm(m,k-1)*n%MOD;
	ll y=(m*(m+1)/2)%MOD*(k-1)%MOD*ksm(m,k-2)%MOD;
	printf("%lld\n",((x-y)%MOD+MOD)%MOD);
	return 0;
}
posted @ 2021-11-10 14:47  ZCETHAN  阅读(33)  评论(0编辑  收藏  举报