for i:=1 to n do begin
read(a[i]);
st[i]:=max(st[i-1],last[a[i]]+1);
q[i]:=i-st[i]+1;
last[a[i]]:=i;
end;
可以發現st陣列單調不減。
於是對於乙個分割點mm有兩種情況:
1、mm左邊一部分st值<=l-1
2、mm右邊一部分st值》=l
因為st是單調的,所以可以用二分法。
左半部分最大值即mm-l,右半部分最大值即q[mm..r]的最大值(可以用rmq演算法來求)。
uses math;
var a,st,q:array[0..200001]of longint;
last:array[-1000001..1000001]of longint;
rmq:array[0..200001,0..21]of longint;
i,j,ans,n,m,l,r,mm,len:longint;
function search(x,y:longint):longint;
var ll,rr,mid:longint;
begin
if st[x]=x then exit(x);
if st[y]ll:=x;rr:=y;
while ll<=rr do begin
mid:=(ll+rr) div 2;
if st[mid]else rr:=mid-1;
end;
exit(ll);
end;
begin
readln(n,m);
for i:=1 to n do begin
read(a[i]);
st[i]:=max(st[i-1],last[a[i]]+1);
q[i]:=i-st[i]+1;
last[a[i]]:=i;
end;
for i:=1 to n do rmq[i,0]:=q[i];
for j:=1 to trunc(ln(n)/ln(2)) do
for i:=1 to n-(1 shl j)+1
do rmq[i,j]:=max(rmq[i,j-1],rmq[i+(1 shl (j-1)),j-1]);
for i:=1 to m
do begin
readln(l,r);
mm:=search(l,r);
if mm>l then ans:=mm-l;
if mm<=r then begin
len:=trunc(ln(r-mm+1)/ln(2));
ans:=max(ans,max(rmq[mm,len],rmq[r-(1 shl len)+1,len]));
end;
writeln(ans);
end;
end.
與眾不同1
題目描述 a是某公司的ceo,每個月都會有員工把公司的盈利資料送給a,a是個與眾不同的怪人,a不注重盈利還是虧本,而是喜歡研究 完美序列 連續的互不相同的序列。a想知道區間 1,r 之間最長的完美序列。輸入格式 第一行兩個整數n,m 1 n,m 2000000 n表示連續n個月,編號為0到n 1,m...
人總想與眾不同
說這個挺無聊的,不過這些年一直遇到這類問題,人們總想表現出很專業,但是太專業了就感覺不專業了。mysql 這個詞,寫起來只要注意了大小寫就可以了,m作為my的首字母大寫,sql作為首字母縮略詞也應該大寫。至於發音,內行人都知道sql可以讀為 sequel 比原本的 ess que ell 省力多了。...
與眾不同 LibreOJ 10121
題目描述 a 是某公司的 ceo,每個月都會有員工把公司的盈利資料送給 a,a 是個與眾不同的怪人,a 不注重盈利還是虧本,而是喜歡研究 完美序列 一段連續的序列滿足序列中的數互不相同。a 想知道區間 l,r l,r 之間最長的完美序列長度。輸入格式 第一行兩個整數 n,m n,m,n n 表示連續...