把博客园图标替换成自己的图标
把博客园图标替换成自己的图标end

P3228 [HNOI2013] 数列 题目分析

题意

小 T 最近在学着买股票,他得到内部消息:F 公司的股票将会疯涨。股票每天的价格已知是正整数,并且由于客观上的原因,最多只能为 \(N\)。在疯涨的 \(K\) 天中小 T 观察到:除第一天外每天的股价都比前一天高,且高出的价格(即当天的股价与前一天的股价之差)不会超过 \(M\)\(M\) 为正整数。并且这些参数满足 \(M(K-1)<N\)。小 T 忘记了这 \(K\) 天每天的具体股价了,他现在想知道这 \(K\) 天的股价有多少种可能。

输入保证 \(20\%\) 的数据 \(M,N,K,P \le 20000\),保证 \(100\%\) 的数据 \(M,K,P \le 10^9\)\(N \le 10^{18}\)

分析

关键转化成差分数组 \(d\)

这样:\(1\leq d_i\leq m\),于是 \(\sum_{i=1}^{k-1}d_i\leq m(k-1)<n\)
所以 \(a_k=a_1+\sum d_i\Rightarrow 1\leq a_1=a_k-\sum d_i\leq n - \sum d_i\)\(a_k\leq n\))。

于是对于任意的 \(d\)\(a_1\) 都有 \(n-\sum d_i\) 种选择。

于是:

\[\begin{aligned} ans&=&&\sum_{d_1=1}^m\dots\sum_{d_{k-1}=1}^m\left(n-\sum_{i=1}^{k-1}d_i\right)\\ &=&&m^{k-1}n-\sum_{d_1=1}^m\dots\sum_{d_{k-1}=1}^m(d_1+\dots+d_{k-1})\\ &=&&m^{k-1}n-m^{k-2}\sum_{d_1=1}^md_1-\dots-m^{k-2}\sum_{d_{k-1}=1}^md_{k-1}\\ &=&&m^{k-1}n-m^{k-2}(k-1)\frac{m(m+1)}{2} \end{aligned} \]

然后做完了,注意 \(P\) 不一定是质数,而且要先对 \(n\) 取模。

代码

时间复杂度 \(\mathcal{O}(\log (KP))\)

#include <iostream>
#include <cstring>
#include <algorithm>
#include <stdlib.h>
#include <cstdio>
#include <vector>
#define int long long
#define N 500005
using namespace std;
//const int mod = 1e9 + 7;
int n,k,m,mod;
int qpow(int a,int b) {
	int res = 1;
	while(b){
		if(b & 1) res = res * a % mod;
		a = a * a % mod;
		b >>= 1;
	}
	return res;
}
signed main(){
	cin >> n >> k >> m >> mod;
	n %= mod;
	if (k == 1) return cout << n % mod,0;
	int t = qpow(m,k - 1);
	cout << (t * n % mod - qpow(m,k - 2) * (k - 1) % mod * ((m * (m + 1) / 2) % mod) % mod + mod) % mod;
	return 0;
}
posted @ 2026-07-15 19:37  high_skyy  阅读(3)  评论(0)    收藏  举报
动态线条
动态线条end
浏览器标题切换
浏览器标题切换end
💬 加载中……