線段樹 差分 p1438 無聊的數列

2022-05-27 16:15:12 字數 1347 閱讀 7505

維護乙個數列,支援兩種操作:

1、1 l r k d:給出乙個長度等於r-l+1的等差數列,首項為k,公差為d,並將它對應加到a[l]~a[r]的每乙個數上。即:令a[l]=a[l]+k,a[l+1]=a[l+1]+k+d,

a[l+2]=a[l+2]+k+2d……a[r]=a[r]+k+(r-l)d。

2、2 p:詢問序列的第p個數的值a[p]。

第一行兩個整數數n,m,表示數列長度和操作個數。

第二行n個整數,第i個數表示a[i](i=1,2,3…,n)。

接下來的m行,表示m個操作,有兩種形式:

1 l r k d

2 p 字母意義見描述(l≤r)。

對於每個詢問,輸出答案,每個答案佔一行。

很明顯,這個題需要資料結構來維護。

維護區間,顯然我們會想到線段樹(貌似寫樹狀陣列更簡單一些.)

維護乙個等差數列會比較麻煩.

但是我們考慮一下等差數列的性質

\[a_-a_i=d

\]此時可以發現,我們維護一下字首和不就好了.!

但是還可能影響到後面的狀態,因此我們在最後減去這些項的和即可.

注意要在乙個修改操作的起始位置賦值成\(k\)(首項),然後後面的每一項加上\(d\)即可.

最後如果右端點不為\(n\),我們需要減去前面等差數列的最後一項.

**

#include#include#define ls o<<1

#define rs o<<1|1

#define n 100008

#define r register

inline void in(int &x)

while(isdigit(s))

x*=f;

}int n,m;

int a[n],tr[n<<2],tg[n<<2];

inline void up(int o)

inline void down(int o,int l,int r)

}void change(int o,int l,int r,int x,int y,int z)

int mid=(l+r)>>1;

down(o,l,r);

if(x<=mid)change(ls,l,mid,x,y,z);

if(y>mid)change(rs,mid+1,r,x,y,z);

up(o);

}int query(int o,int l,int r,int x,int y)

int main()

else

}}

P1438 無聊的數列(線段樹 差分)

題目描述維護乙個數列 ai,支援兩種操作 1 l r k d 給出乙個長度等於 r l 1 的等差數列,首項為 k,公差為 d,並將它對應加到 l,r 範圍中的每乙個數上。即 令 al al k ar ar k r l d 2 p 詢問序列的第 p 個數的值 ap。輸入格式 第一行兩個整數數 n,m...

P1438 無聊的數列 線段樹

無聊的yyb總喜歡搞出一些正常人無法搞出的東西。有一天,無聊的yyb想出了一道無聊的題 無聊的數列。k峰 這題不是傻x題嗎 維護乙個數列,支援兩種操作 1 1 l r k d 給出乙個長度等於r l 1的等差數列,首項為k,公差為d,並將它對應加到a l a r 的每乙個數上。即 令a l a l ...

洛谷P1438 無聊的數列 線段樹,差分

題目背景 無聊的yyb總喜歡搞出一些正常人無法搞出的東西。有一天,無聊的yyb想出了一道無聊的題 無聊的數列。k峰 這題不是傻x題嗎 題目描述 維護乙個數列,支援兩種操作 1 1 l r k d 給出乙個長度等於r l 1的等差數列,首項為k,公差為d,並將它對應加到a l a r 的每乙個數上。即...