題目描述
維護乙個數列 \(a_i\),支援兩種操作:
1 l r k d:給出乙個長度等於 \(r-l+1\) 的等差數列,首項為 \(k\),公差為 \(d\),並將它對應加到 \([l,r]\) 範圍中的每乙個數上。即:令 \(a_l=a_l+k,a_=a_+k+d\ldots a_r=a_r+k+(r-l) \times\)。
2 p:詢問序列的第 \(p\) 個數的值 \(a_p\)。
輸入格式
第一行兩個整數數 \(n,m\) 表示數列長度和操作個數。
第二行 \(n\) 個整數,第 \(i\) 個數表示 \(a_i\)。
接下來的 \(m\) 行,每行先輸入乙個整數 \(opt\)。
若 \(opt=1\) 則再輸入四個整數 \(l\ r\ k\ d\);
若 \(opt=2\) 則再輸入乙個整數 \(p\)。
輸出格式
對於每個詢問,一行乙個整數表示答案。
差分+線段樹
就沒什麼好說的吧
#include#include#include#includeusing namespace std;
const int n=2e5+10;
#define int long long
int a[n],n,m;
struct segtree[n<<2];
#define ls p<<1
#define rs p<<1|1
#define mid ((l(p)+r(p))>>1)
void build(int p,int l,int r)
build(ls,l,mid);
build(rs,mid+1,r);
sum(p)=sum(ls)+sum(rs);
}inline void pushdown(int p)
void update(int p,int l,int r,int d)
if(add(p))pushdown(p);
if(l<=mid)update(ls,l,r,d);
if(r>mid)update(rs,l,r,d);
sum(p)=sum(ls)+sum(rs);
}int query(int p,int l,int r)
signed main()
build(1,1,n);
int opt,l,r,k,d;
while(m--)else
}}
luogu P1438 無聊的數列
區間 l 到 r 內加等差數列 已知首項為 k 公差為 d 那麼每一位加的數值為 k i l d l i r k i d l d l i r k l d i d l i r 我們可以分別加一下 k l d 和 i d 前者可以算出來,直接區間加就可以 後者的話,先維護一下 l,r 內的下標和 結合律...
luogu P1438 無聊的數列(線段樹 差分)
題意 對於乙個陣列 a aa 現在有兩個操作 思路 操作一 因為對於乙個區間 l,r l,r l,r 在第 l ll 位上加上 k kk 在區間 l,r l,r l,r 上加上 d dd 再在第 r 1 r 1r 1 位上加上 k r l d k r l d k r l d 這樣對於陣列每一位上的修...
P1438 無聊的數列
板子題 按照ppt所說的,預留0號位和n 1號位,0號位位於2的若干次方的位置。但是我試了一下。沒有嚴格要求的這樣的寫法,這題也能a,資料有點水。include include include include include include include include include inclu...