【洛谷P3228】数列

题目

题目链接:https://www.luogu.com.cn/problem/P3228
小 T 最近在学着买股票,他得到内部消息:F 公司的股票将会疯涨。股票每天的价格已知是正整数,并且由于客观上的原因,最多只能为 n。在疯涨的 k 天中小 T 观察到:除第一天外每天的股价都比前一天高,且高出的价格(即当天的股价与前一天的股价之差)不会超过 mm 为正整数。并且这些参数满足 m(k1)<n。小 T 忘记了这 k 天每天的具体股价了,他现在想知道这 k 天的股价有多少种可能。
m,k,p109;n1018

思路

不难想到把每天的股价差分一下。那么现在问题转化为对于一个长度为 k1 的序列 a,且 a 的每一个元素都不超过 m,它的贡献是 (nk1i=1ai)。求所有满足要求的序列的贡献之和。
显然差分序列一共有 mk1 种。记 ai,j 为第 i 种差分序列的第 j 个元素。那么答案即为

i=1mk1(nj=1k1ai,j)

=n×mk1i=1mk1j=1k1ai,j

考虑减号后面一部分。也就是所有差分序列的所有元素和。
可以发现每一个 [1,m] 间的数字的出现次数都是一样的。因为对于两个数字 x,y,我们把所有差分序列中 xy 的位置交换,那么这 mk1 个差分序列必然和没有交换前的一致。
由于所有数字出现次数之和为 mk1×(k1),所以每一个数字的出现次数就为 mk2×(k1)。所以答案就是

n×mk1m(1+m)2×mk2×(k1)

代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

ll n,m,k,p;

ll fpow(ll x,ll k)
{
	ll ans=1;
	for (;k;k>>=1,x=x*x%p)
		if (k&1) ans=ans*x%p;
	return ans;
}

int main()
{
	scanf("%lld%lld%lld%lld",&n,&k,&m,&p);
	printf("%lld",(n%p*fpow(m,k-1)%p-fpow(m,k-2)*(k-1)%p*((1+m)*m/2%p)%p+p)%p);
	return 0;
}
posted @   stoorz  阅读(41)  评论(0编辑  收藏  举报
编辑推荐:
· Linux glibc自带哈希表的用例及性能测试
· 深入理解 Mybatis 分库分表执行原理
· 如何打造一个高并发系统?
· .NET Core GC压缩(compact_phase)底层原理浅谈
· 现代计算机视觉入门之:什么是图片特征编码
阅读排行:
· 手把手教你在本地部署DeepSeek R1,搭建web-ui ,建议收藏!
· Spring AI + Ollama 实现 deepseek-r1 的API服务和调用
· 数据库服务器 SQL Server 版本升级公告
· 程序员常用高效实用工具推荐,办公效率提升利器!
· C#/.NET/.NET Core技术前沿周刊 | 第 23 期(2025年1.20-1.26)
历史上的今天:
2020-06-10 【POJ2942】Knights of the Round Table
点击右上角即可分享
微信分享提示