JZOJ 3.18 1507——【普及模拟】数列

题目描述

给定一个等差数列,第一项是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


题解:
步骤一:先将等差数列的个数求出来。
步骤二:再将等比数列求出来,并存在数组里。
步骤三:扫一遍等比数组,将既是等比的又是等差的去重。


代码如下:

var
  x,y,q,p,n,s,ss:int64;
  i:longint;
  a:array[0..50] of int64;
begin
  assign(input,'shulie.in');
  assign(output,'shulie.out');
  reset(input);
  rewrite(output);
  read(x,y,q,p,n);
  if n>=x then s:=(n-x) div y+1;
  if p=1 then
    if (((q-x) mod y<>0) and (q<=n)) or ((qand (q<=n)) then inc(s) else s:=s
  else
    begin
      ss:=1;
      a[1]:=q;
      while a[ss]*p<=n do
        begin
          inc(ss);
          a[ss]:=a[ss-1]*p;
        end;
      s:=s+ss;
      for i:=1 to ss do
        if (a[i]-x>=0) and ((a[i]-x) mod y=0) then dec(s);
    end;
  write(s);
  close(input);
  close(output);
end.

转载于:https://www.cnblogs.com/Comfortable/p/8412365.html

你可能感兴趣的:(JZOJ 3.18 1507——【普及模拟】数列)