Description
Data Constraint
Solution
看到数据范围就应该要很明显地发现找循环节,因为循环节最长只有150个数。
先处理出循环节,然后要开始考虑,在前面还没有开始循环时取若干个数,循环部分选出一个数每一节取,最后一个循环区间再取若干个数。思想很明显了,先做一次最长不下降子序列,再一个个区间添加,当答案增加值只有1时,说明不会再有更优的贡献,然后就能跳过剩下的,把最后一个区间添加进去再求一遍。至此,就能求出答案了。
Code
var
t,q1,q2,q3,p,x:array[0..1000] of longint;
d:array[0..1000000] of longint;
i,a,b,c,mo,s1,s2,s3,wz,tot:longint;
num,n,ans:int64;
function min(x,y:longint):longint;
begin
if x<y then exit(x);exit(y);
end;
procedure deal;
var i:longint;
begin
for i:=1 to s1 do q1[i]:=x[i];
for i:=1 to s2 do q2[i]:=x[i+s1];
for i:=1 to s3 do q3[i]:=q2[i];
end;
function ef(x:longint):longint;
var l,r:longint;
begin
l:=0;r:=ans;
while l<r do
begin
ef:=(l+r+1)div 2;
if d[ef]<=x then l:=ef else r:=ef-1;
end;
exit(l+1);
end;
begin
readln(n);
readln(x[1],a,b,c,mo);
p[x[1]]:=1;
i:=1;
while i<n do
begin
inc(i);
x[i]:=(x[i-1]*x[i-1]*a+x[i-1]*b+c) mod mo;
if p[x[i]]<>0 then
begin
s1:=p[x[i]]-1;s2:=i-p[x[i]];s3:=(n-s1) mod s2;
deal;
break;
end;
p[x[i]]:=i;
end;
fillchar(d,sizeof(d),$7f div 2);d[0]:=0;
if s2=0 then
begin
for i:=1 to n do
begin
wz:=ef(x[i]); d[wz]:=min(d[wz],x[i]);
if wz>ans then ans:=wz;
end;
writeln(ans);
exit;
end;
for i:=1 to s1 do
begin
wz:=ef(q1[i]); d[wz]:=min(d[wz],q1[i]);
if wz>ans then ans:=wz;
end;
num:=(n-s1) div s2;
while num>0 do
begin
dec(num);tot:=ans;
for i:=1 to s2 do
begin
wz:=ef(q2[i]); d[wz]:=min(d[wz],q2[i]);
if wz>ans then ans:=wz;
end;
if ans-tot=1 then break;
end;
tot:=ans;
ans:=ans+num;
num:=ans;ans:=tot;
for i:=1 to s3 do
begin
wz:=ef(q3[i]); d[wz]:=min(d[wz],q3[i]);
if wz>ans then ans:=wz;
end;
ans:=num+(ans-tot);
writeln(ans);
end.