看到資料範圍就應該要很明顯地發現找迴圈節,因為迴圈節最長只有150個數。
先處理出迴圈節,然後要開始考慮,在前面還沒有開始迴圈時取若干個數,迴圈部分選出乙個數每一節取,最後乙個迴圈區間再取若干個數。思想很明顯了,先做一次最長不下降子串行,再乙個個區間新增,當答案增加值只有1時,說明不會再有更優的貢獻,然後就能跳過剩下的,把最後乙個區間新增進去再求一遍。至此,就能求出答案了。
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 xthen
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 ldo
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 ido
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
dobegin
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.
GDOI2017模擬9 10 子串
給出n個字串si,m次詢問,第i次詢問sli sri這些字串中有多少個是字串pi的母串。si pi 5 105顯然我們需要離線回答。把所有的pi建一棵ac自動機。然後把詢問差分,變成字首的形式。那麼我們只需要每次把乙個主串放在ac自動機上跑一跑,然後把經過的點和它在fail樹中到根的路徑全部 1.但...
最長不下降子串行
a1 t0 an a an 1 2 b an c d n 1 求該序列最長不下降子串行長度 n不是很大顯然可以暴力。n很大呢?那就不斷減迴圈節長度直至減到乙個閾值內,再暴力。正確性顯然,只要閾值不要設太小。include include include define fo i,a,b for i a...
最長不下降子串行
最長不下降子串行解法 第一種就是普通的dp方法 for int i 1 i n i dp 0 1 for int i 1 i n i ans max ans,dp i cout 主要記錄一下n logn的寫法 二分 主要思路 用乙個陣列 b 來記錄最長的子串行 一開始讓b 1 a 1 陣列a為輸入的...