等差子數列 HihoCoder 1710

2021-09-16 21:27:36 字數 2603 閱讀 3643

給定n個整數a1, a2, … an,小hi會詢問你m個問題。

對於每個問題小hi給出兩個整數l和r(l ≤ r),請你找出[al, al+1, al+2, … ar]中最長的等差連續子數列,並輸出其長度。

例如[2, 3, 5, 7, 9]中最長的等差連續子數列是[3, 5, 7, 9]長度為4。

input

第一行包含兩個整數n和m。

第二行包含n個整數a1, a2, … an。

以下m行每行包含兩個整數l和r,代表一次詢問。

對於30%的資料,1 ≤ n, m ≤ 1000

對於100%的資料,1 ≤ n, m ≤ 100000 0 ≤ ai ≤ 10000000

output

依次對於每個詢問輸出乙個整數,代表答案。

先寫了一發奇奇怪怪的線段樹。。。雖然知道大概**錯了,但是沒改出來。。。

最後用的是rmq

首先舉個栗子

1 2 3 5 7 9 8 7 6 5

我們可以看出來1 2 3 是個等差數列,3 5 7 9 是個等差數列,9 8 7 6 5是個等差數列,那麼我們可以把這個陣列分為三段

下面是幾個陣列的變數解釋;

sum[i] : 第i個數字所在的等差數列的等差值

l[i] :第i個數字所在的等差數列的最右端的開始的下標

r[i] :第i個數字所在的等差數列最左邊的結束的下標

那麼剛剛上面的那個例子的sum,l,r的值就是下面的表12

3579

8765

sum112

22-1-1

-1-1-1l

1133

3666

66r3

3666

1010

1010

10那麼我們把每次查詢的【l,r】的結果分為三個部分的最大值,r[l]-l+1,r-l[r]+1,r[l]+1~l[r]-1

分別代表了從l到l所在的段的結束處的元素個數,從r所在段的開始處到r處的元素個數,和這中間的那一段的sum的值

那麼如果我們想要計算【2,9】之間的最長連續等差序列,也就是2 3 5 7 9 8 7 6 之間的最長連續子串行

那麼對於這次查詢,可以把這個查詢根據等差數列分的段分為3段2 3 | 5 7 | 9 8 7 6這三段

2 3這一段一共有2個數

5 7這一段的最大的sum值是3

9 8 7 6這一段一共有4個數

所以這一段的最長連續子串行的個數就是4

對於中間段r[l]+1到l[r]-1這個區間裡找sum的最大值用的是rmq查詢。。。

特別的如果l和r在同乙個等差數列的段中,那麼答案就是r-l+1;

* 對於查詢中間段r[l]+1到l[r]-1這個區間裡找sum的最大值這個步驟,要用到rmq我以前一直寫線段樹,第一次寫rmq,還是記錄一下:

首先預處理一下dp陣列(聽大佬講,rmq用的思想是dp):

dp[i][j]:第i位數字到它後面的2j個位置的最大值(i後面的乙個位置是它本身)

首先預處理dp[i][0]=sum[i];

下面的我們來舉個栗子

現在有4個數字 1 2 3 4 5

我們要算dp[1][2],也就是1後面的包括它本身的四個數字

那麼我們可以把1 2 3 4 分為1 2 一段 3 4 一段

1 2 是1後面包括他本身的兩個數字 他們的最大值也就是 dp[i][2-1];

3 4 shi 3後面包括他本身的兩個數字,3和1之間隔了21個數字,也就是dp[i+(1<<(j-1))][j-1];

所以dp[i][j]=max (dp[i][j-1] , dp[i+(1<<(j-1))][j-1]);

然後查詢的時候,令k為滿足2k

<=r-l+1的最大整數,則以l開頭,以r結尾的 兩個 長度為2k的區間合起來覆蓋了查詢區間【l,r】,取最大值就好了

#include

#include

#include

using namespace std;

int n,m,ans;

int a[

100010];

int l[

100010

],r[

100010

],sum[

100010

],dp[

100010][

25];void

init_rmq()

}}intrmq

(int l,

int r)

intmain()

}for

(int i=

1; i<=n; i++

)printf

("%d "

,l[i]);

printf

("\n");

for(

int i=

1; i<=n; i++

)printf

("%d "

,r[i]);

init_rmq()

;int l,r;

while

(m--)}

}

最長連續等差子數列

描述 給定乙個長度為n的整數數列,你需要在其中找到最長連續子數列的長度,並滿足這個子數列是等差的。注意公差小於或等於0的情況也是允許的。輸入 第一行為測試資料的組數t 1 t 100 請注意,任意兩組測試資料之間是相互獨立的。每組資料報含兩行 第一行為乙個整數n 1 n 100 表示給定數列長度。第...

等差子數列 rmq 分塊思想

等差子數列 題解 看到這一題,我的想法是利用分塊去寫,將等差數列分為一塊,但是由於等差數列有連續性,故利用分塊思想,將解答案分為三步,兩邊角的,最大等差數列長度,再求中間部分的最大序列長度,中間部分可以利用rmq去求,因為是數列,所以求區間最值用rmq就很方便了 ac include include...

最長等差數列 最長等差數列 及子串行分析

今日面試題 最長等差數列 給定未排序的陣列,請給出方法找到最長的等差數列。子串行分析 原題給定長度為n的整數數列 a0,a1,an 1,以及整數s。這個數列會有連續的子串行的整數總和大於s的,求這些數列中,最小的長度。分析如果只是像題目這樣的描述,沒有強調正數,可以採用o n 2 的方法。但是,很多...