【HNOI2013】数列

题目

小T最近在学着买股票,他得到内部消息:F公司的股票将会疯涨。

股票每天的价格已知是正整数,并且由于客观上的原因,最多只能为N。在疯涨的K天中小T观察到:除第一天外每天的股价都比前一天高,且高出的价格(即当天的股价与前一天的股价之差)不会超过M,M为正整数。并且这些参数满足M(K-1)

分析

我们发现若是从他们的各自股价开始入手,问题会变得很困难,
为什么呢?因为股价本身就是一个递增的值,不方便我们讨论方案数
于是我们可以从有限定的m入手,即每两天之间股价的差:
a[1],a[2],a[3],a[4]..a[k-1]
那么这样就不用去管每个a[i]的值之间的关系了。
若是确定了这k-1个数,那么很明显会有 na[i] 的方案(即第一天的股价的值)
那么总的方案就是 na[i]
然而这样想上面的数列一共有 mk1 ,我们先提取n出来,就是 nmk1
而a[i]我们可以这样处理,因为一共有 mk1 个数列,也就是有 mk1(k1) 个数
而且每一个数的范围都是1..m,出现的次数都是一样的也就是 mk1k1/m=mk2(k1)
这样的话,用等差数列求和,每m个数配一组总的就是 mk2(k1)(m+1)m/2
所以答案就是 nmk1mk2(k1)(m+1)m/2
到此便很好的解决问题了。这题关键是转换成差来思考。

#include<iostream> 
#include<algorithm>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<cstdio>
using namespace std;
long long ans,n,m,k,p;
long long power(long long x,long long y,long long z){
    if (y==1) return x;
    else {
        long long e=power(x,y>>1,z);
        e=(e*e)%p;
        if (y%2==1) e=(e*x)%p;
        return e;
    }
}
int main(){
    scanf("%lld%d%d%d",&n,&k,&m,&p);
    n=n%p;
    ans=(power(m % p,k-1,p)*(n%p))%p;
    ans-=((power(m % p,k-2,p)*(k-1)% p)*(((m+1)*m/2)% p))%p;
    ans=(ans+p)%p;
    printf("%d",ans);
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值