題目大意 :給你乙個整數序列,定義乙個合法子串為子串內所有數互不相同,會有很多詢問,求區間$[l,r]$內最長連續合法子串長度
一道思維不錯的$rmq$題,noip要是考這種題可能會考掛一片
預處理出$f_$陣列表示以i結尾的最長子串的起始位置,需要乙個輔助$last$陣列,表示某個數上一次出現的位置
那麼$f_=max(f_,last[a_]+1)$
再$rmq$預處理出區間內任意乙個點結尾的最長子串長度
對於乙個詢問$[l,r]$,並不能直接用$rmq$求出答案,因為有一些在$[l,r]$結尾的最長子串的起始位置可能超出$l$
然後發現$f_$陣列是遞增的,所以對於乙個詢問,二分出乙個位置,這個位置結尾的最長子串的左端點,是最後乙個左端點超出$l$的位置
顯然,答案要麼是二分出的位置$k$到$l$的距離,或者是在$k+1$到$r$之間結尾的最長子串長度
時間$o(nlogn+mlogn)$
1 #include 2 #include 3 #include 4 #include 5#define n 200010
6#define m 2001000
7#define maxn 1000000
8#define inf 0x3f3f3f3f
9using
namespace
std;
1011
intn,m;
12int
gint()
1316
while(c>='
0'&&c<='9')
17return ret*fh;18}
1920
int a[n],ma[n][20
],la[m],f[n],lg[n];
21int query(int x,int
y)26
27int
main()
28else
43for(int i=1;i<=n;i++) ma[i][0]=i-f[i]+1
; 44
for(int j=1;j<=lg[n];j++)
45for(int i=1;i+(1
<1
<=n;i++)
46 ma[i][j]=max(ma[i][j-1],ma[i+(1
<<(j-1))][j-1
]);47
intx,y;
48for(int i=1;i<=m;i++)
4958 printf("
%d\n
",max(ans-x+1,query(ans+1
,y)));59}
60return0;
61 }
LOJ10121 與眾不同
題目藍鏈 首先要預處理出每乙個位置的上乙個與當前位置的數相同的位置,然後就可以利用它求出 pos i 表示以第 i 個數為結尾的最長完美序列的起始位置。然後就可以求出每乙個位置往前最多可以選多少個數,我們用rmq來維護一下這個東西 詢問的時候,由於 pos 單調不降,直接在 l,r 中二分一下找到最...
與眾不同 LibreOJ 10121
題目描述 a 是某公司的 ceo,每個月都會有員工把公司的盈利資料送給 a,a 是個與眾不同的怪人,a 不注重盈利還是虧本,而是喜歡研究 完美序列 一段連續的序列滿足序列中的數互不相同。a 想知道區間 l,r l,r 之間最長的完美序列長度。輸入格式 第一行兩個整數 n,m n,m,n n 表示連續...
與眾不同2
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 因為...