GDOI2017 最長不下降子串行

2021-07-25 08:55:37 字數 2431 閱讀 4841

看到資料範圍就應該要很明顯地發現找迴圈節,因為迴圈節最長只有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為輸入的...