【洛谷P3228】數列
阿新 • • 發佈:2021-06-10
題目
題目連結:https://www.luogu.com.cn/problem/P3228
小 T 最近在學著買股票,他得到內部訊息:F 公司的股票將會瘋漲。股票每天的價格已知是正整數,並且由於客觀上的原因,最多隻能為 \(n\)。在瘋漲的 \(k\) 天中小 T 觀察到:除第一天外每天的股價都比前一天高,且高出的價格(即當天的股價與前一天的股價之差)不會超過 \(m\),\(m\) 為正整數。並且這些引數滿足 \(m(k-1)<n\)。小 T 忘記了這 \(k\) 天每天的具體股價了,他現在想知道這 \(k\) 天的股價有多少種可能。
\(m,k,p\leq 10^9;n\leq 10^{18}\)
思路
不難想到把每天的股價差分一下。那麼現在問題轉化為對於一個長度為 \(k-1\) 的序列 \(a\),且 \(a\) 的每一個元素都不超過 \(m\),它的貢獻是 \((n-\sum^{i=1}_{k-1}a_i)\)。求所有滿足要求的序列的貢獻之和。
顯然差分序列一共有 \(m^{k-1}\) 種。記 \(a_{i,j}\) 為第 \(i\) 種差分序列的第 \(j\) 個元素。那麼答案即為
考慮減號後面一部分。也就是所有差分序列的所有元素和。
可以發現每一個 \([1,m]\)
由於所有數字出現次數之和為 \(m^{k-1}\times (k-1)\),所以每一個數字的出現次數就為 \(m^{k-2}\times (k-1)\)。所以答案就是 \[n\times m^{k-1}-\frac{m(1+m)}{2}\times m^{k-2}\times (k-1) \]
程式碼
#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; }