jzoj P1507【普及模拟】数列

题目描述

给定一个等差数列,第一项是a, 从第二项开始,每项与前一项的差都是一个定值b。如果用数学形式来表示,那么可以表示成 a + b × x , 其中 x≧0,且是整数。例如: a = 1, b=2, 那么这个等差数列就是:1,3,5,7,9…

再给定一个等比数列,第一项是c, 从第二项开始,每项是前一项的d倍。如果用数学形式来表示等比数列,则是 c ×(dy)。 其中 y≧0, 且是整数。例如: c = 2, d = 3, 那么这个等比数列就是:2,6,18,54…

你的任务是计算在1至upperBound内的正整数,有多少正整数是“合法”的?

所谓的“合法”是指:该整数属于上面给定的等差数列的某项或者属于等比数列的某项,或者既属于等差数列的项也属于等比数列的项。

输入

一行,5个整数,分别是a,b,c,d,upperBound。

(1≤a,b,c,upperBound≤1012, 1≤d≤105。)

对于80%的数据,1≤upperBound≤1000000。

输出

一个整数,表示“合法”正整数的个数。

样例输入

1 1 1 2 1000

样例输出

1000

题解;
1.等差数列因为2个数之间的值是固定值b,若a<=u就可以直接求出a~u之间等差数列的数量(u-a) div b+1。
2.等比数列直接做就好了,因为是逐级乘法,所以速度挺快的,不过要判断*1的情况,如果等比数列某项c小于等差数列的初始项a就一定不在等差数列中,这时候就可以累加了,c=a的时候在等差数列中已经累加过了,如果c>a的话就判断(c-a) mod b等不等于0,等于0就是在等差数列中,这时候不累加,否则累加。

var
    ans,a,b,c,u:int64;
    d:longint;
begin
    readln(a,b,c,d,u);
    if a<=u
       then ans:=(u-a) div b+1;
        while c<=u do
              begin
                 if c<a then inc(ans)
                        else if c>a then
                                if (c-a) mod b<>0 then inc(ans);
                 c:=c*d;
                 if d=1 then break;
              end;
    writeln(ans);
end.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值