給定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 的方法。但是,很多...