題目描述
維護乙個數列,支援兩種操作:
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 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陣列不動,重新開個陣列(可以說這是差分陣列),用線段樹維護;
線段樹維護每個區間的公差值,每個區間的左端點l直接加首項,然後[l+1,r]每個點加上公差,最後區間端點r+1,減去[l,r]區間加上的值(比較像差分陣列維護);那麼線段樹維護的作用就完成了,最後求第p個數的值,只要a[p]+區間[1,p]的和;
**:
#include
using
namespace std;
int a[
100100];
int q,l,r,k,d;
int x,y,z,sum;
struct nodetree[
400100];
inline
void
build
(int k,
int ll,
int rr)
int m=
(ll+rr)
>>1;
build
(k<<
1,ll,m)
;build
(k<<1|
1,m+
1,rr);}
inline
voidpd(
int k)
}inline
void
change
(int k)
pd(k)
;int m=
(tree[k]
.l+tree[k]
.r)>>1;
if(x<=m)
change
(k<<1)
;if(y>m)
change
(k<<1|
1); tree[k]
.w=(tree[k<<1]
.w+tree[k<<1|
1].w);
}inline
void
ask(
int k)
pd(k)
;int m=
(tree[k]
.l+tree[k]
.r)>>1;
if(x<=m)
ask(k<<1)
;if(y>m)
ask(k<<1|
1);}
intmain()
else
}return0;
}
牛牛的等差數列 線段樹
這裡的突破口在於小於等於25且大於等於3的質數連乘在1e8左右,所以,我們可以在操作上,將其看作對1e8去求模,而不是對每個都進行預處理。時間複雜度 include include include include include include include include include inc...
區間變成等差數列(線段樹)
keven 特別喜歡線段樹,他給你乙個長度為 n的序列,對序列進行m次操作。操作有兩種 1lrk 表示將下標在 l,r 區間內的數字替換成 k,k 1,k r l 2lr 表示查詢區間 l,r 的區間和 第一行兩個整數 n m,表示序列的長度和操作次數 1 n,m 2e5 第二行 n個整數,表示序列...
線段樹專題 樹上等差數列
題目大意 思路 線段樹維護區間的a1和an,公差為1。poj3468 include define ll long long using namespace std define max node 400005 define max 100005 struct node node max node ...