洛谷 P1438 無聊的數列

2021-08-08 14:09:29 字數 1436 閱讀 1857

題目背景

無聊的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 2

1 2 3 4 5

1 2 4 1 2

2 3

輸出樣例#1:

6 說明

資料規模:

0≤n,m≤100000

|a[i]|,|k|,|d|≤200

hint:

有沒有巧妙的做法?

//看的狗哥的**,不明白標記下放怎麼不對

#include

#include

#include

#include

using namespace std;

#define maxn 100005

struct segment_treetre[maxn<<2];

inline void read(int &x)

while(c>='0'&&c<='9') x

*=f;

}void modify(int u,int l,int r,int k,int d)

int mid=tre[u].l+tre[u].r>>1;

if(l<=mid) modify(u<<1,l,r,k,d);

if(r>mid) modify(u<<1|1,l,r,k,d);

}int query(int u,int

pos)

void build(int u,int l,int r)

int mid=l+r>>1;

build(u<<1,l,mid),build(u<<1|1,mid+1,r);

tre[u].val=tre[u<<1].val+tre[u<<1|1].val;

}int main()

return

0;}

洛谷 P1438 無聊的數列

1 多次對於區間加上乙個等差數列,引數為l,r,k,d,表示首項為k,公差為d,將乙個長度r l 1的等差數列加到區間l.r上 2 詢問乙個值a i 要加上乙個等差數列,很容易想到差分,因此將題目簡化至下 1 將a l 加上k 2 將a l 1.r 加上d 3 將a r 1 r l d k 而查詢的...

洛谷 P1438 無聊的數列

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

洛谷 P1438 無聊的數列

lazytag記錄一下某個區間需要加的等差數列的首項和公差。由於區間長度已知 r l 1 僅由此就可以推出這個區間每乙個數要加上的數。可以發現兩個等差數列每一項相加,得到的還是等差數列,而且是首項和公差分別相加。對於區間的分解 標記的下傳 要用等差數列通項 求和 求項數公式手算一下。由父區間應加上的...