維護乙個數列,支援兩種操作:
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)。
輸出格式:
對於每個詢問,輸出答案,每個答案佔一行。
輸入樣例
5 21 2 3 4 5
1 2 4 1 2
2 3
輸出樣例
6
資料規模:
0≤n,m≤100000
|a[i]|,|k|,|d|≤200
神奇的線段樹,本來線段樹的用法都是靜態地操作,現在發現連這樣的動態的等差數列都可以新增
其實關鍵是利用了差分的原理,通過線段樹可以很好地發揮差分的優勢
#include#include#define ls x<<1
#define rs x<<1|1
using
namespace
std;
const
int mxn=100010
;int
n,m,k,d;
int a[mxn],laz[mxn<<2],tree[mxn<<2
];inline
intin()
while(ch>='
0' && ch<='
9') s=s*10+ch-'
0',ch=getchar();
return s*f;
}void pd(int x,int l,int r,int
mid)
}void add(int x,int l,int r,int ql,int qr,int
val)
int mid=(l+r)>>1
; pd(x,l,r,mid);
if(ql<=mid) add(ls,l,mid,ql,qr,val);
if(qr>mid) add(rs,mid+1
,r,ql,qr,val);
tree[x]=tree[ls]+tree[rs];
}int qur(int x,int l,int r,int ql,int
qr)
intmain()
else
if(cas==2
) }
return0;
}
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 無聊的數列
一開始嚇死,給區間加上乙個等差數列?然後就發現我們只要維護題目裡說的k,d兩個之就好了 比如我讀入是1,x,y,k,d 那麼對於在x y這個區間裡面的小區間l r 小區間的k,d值相應就是 k k d l x d d 這個很顯然把 換句話說,x y變成乙個等差序列,那麼對於i小區間l r顯然也是乙個...
洛谷 線段樹 P1438 無聊的數列
無聊的yyb總喜歡搞出一些正常人無法搞出的東西。有一天,無聊的yyb想出了一道無聊的題 無聊的數列。k峰 這題不是傻x題嗎 維護乙個數列,支援兩種操作 1 1 l r k d 給出乙個長度等於r l 1的等差數列,首項為k,公差為d,並將它對應加到a l a r 的每乙個數上。即 令a l a l ...