無聊的yyb總喜歡搞出一些正常人無法搞出的東西。有一天,無聊的yyb想出了一道無聊的題:無聊的數列。。。(k峰:這題不是傻x題嗎)
維護乙個數列,支援兩種操作:
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)。
輸出格式:
對於每個詢問,輸出答案,每個答案佔一行。
輸入樣例#1:
5 21 2 3 4 5
1 2 4 1 2
2 3
輸出樣例#1:
6
資料規模:
0≤n,m≤100000
|a[i]|,|k|,|d|≤200
hint:
有沒有巧妙的做法?
solution:
注意到等差數列公差為$d$,我們可以將原序列差分,設差分後的陣列為$sum$,這樣對$[l,r]$區間修改等同於對差分後的序列進行如下操作:
1、$sum[l]+k,\;sum[r+1]-k$
2、$sum[i]+d,\;i\in [l+1,r],\;\;sum[r+1]-d(r-l)$
於是就很自然的可以用線段樹維護$sum$陣列(差分後的陣列),查詢第$k$個數等同於查詢$a[1,k]$的$sum$和加上原數$a[k]$。
這樣就是區間修改,區間查詢的模板了。
**:
#include#define il inline#define ll long long
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
using
namespace
std;
const
int n=100005
;int n,m,sum[n<<2],add[n<<2
],a[n];
il int
gi()
il void pushup(int rt)
il void pushdown(int rt,intk)}
il void build(int l,int r,int
rt)il
void update1(int l,int r,int c,int l,int r,int
rt) pushdown(rt,r-l+1
);
int m=l+r>>1
;
if(l<=m)update1(l,r,c,lson);
if(mpushup(rt);
}il
int query(int l,int r,int l,int r,int
rt)int
main()
else
}return0;
}
P1438 無聊的數列
板子題 按照ppt所說的,預留0號位和n 1號位,0號位位於2的若干次方的位置。但是我試了一下。沒有嚴格要求的這樣的寫法,這題也能a,資料有點水。include include include include include include include include include inclu...
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 無聊的數列
區間問題,肯定是線段樹了,但是區間加的是乙個等差數列,怎麼辦呢 我們可以通過差分來維護。蛤是差分?搞乙個陣列專門差分,在陣列中記錄 對於l r的區間加x,在l位置加上x,在r 1位置減去x。當查詢某個數值時,該位置上的數加上差分陣列中1 該位置的字首和,自己出組數試一下發現這樣是對的 我們線段樹剛好...