53 線段樹區間修改(線段樹《重點》)

2021-08-21 03:50:24 字數 1549 閱讀 1680

昨天學習了線段樹這樣一種極其重要的演算法,在競賽是具有廣泛的運用。可以用線段樹對桶等其他的演算法和結構進行維護。

基本題目如下:

【題目描述】

如題,已知乙個數列,你需要進行下面兩種操作:

1.將某區間每乙個數加上x

2.求出某區間每乙個數的和

第一行包含兩個整數n、m,分別表示該數列數字的個數和操作的總個數。

第二行包含n個用空格分隔的整數,其中第i個數字表示數列第i項的初始值。

接下來m行每行包含3或4個整數,表示乙個操作,具體如下:

操作1: 格式:1 x y k 含義:將區間[x,y]內每個數加上k

操作2: 格式:2 x y 含義:輸出區間[x,y]內每個數的和

輸出包含若干行整數,即為所有操作2的結果。

5 5

1 5 4 2 3

2 2 4

1 2 3 2

2 3 4

1 1 5 1

2 1 4

11

820

對於30%的資料:n<=8,m<=10

對於70%的資料:n<=1000,m<=10000

對於100%的資料:n<=100000,m<=100000

(資料保證在int64/long long資料範圍內)

#include#include#include#include#includeusing namespace std;

#define lson rt*2

#define rson rt*2+1

#define data(x) t[x].data

#define lside(x) t[x].l

#define rside(x) t[x].r

#define sign(x) t[x].c

#define width(x) (rside(x)-lside(x)+1)

const int n=100005;

long long n=0,m=0,a=0,x=0,y=0,z=0;

struct node

t[n*4];

void pushup(int rt)

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

int m=l+r>>1;

build(l,m,lson);

build(m+1,r,rson);

pushup(rt);//遞迴構造線性樹

return ;

}void pushdown(int rt)

void update(int l,int r,long long c,int rt)

pushdown(rt);

int m=(lside(rt)+rside(rt))/2;

if(l<=m)

update(l,r,c,lson);

if(m這樣就是乙個線段樹的模板,大部分借用了老師的程式,自己稍微修改,加入了自己的特色。

順便弄清楚了%i64d和%lld什麼時候使用的道理..........

線段樹 區間修改

我們對於線段樹的區間修改你可以用乙個最傻的辦法迴圈進行單點修改 時間複雜度太高十分麻瓜 所以,我們要用乙個聰明的做法延遲標記 lazy 我們在執行修改指令時,同樣可以在 l pl pr r 的情況下立即返回,只不過在回溯之前向節點p增加乙個標記,標識 該節點曾經被修改過,但其子節點尚未被更新 如果在...

操作格仔 單點修改線段樹

問題描述 有n個格仔,從左到右放成一排,編號為1 n。共有m次操作,有3種操作型別 1.修改乙個格仔的權值,2.求連續一段格仔權值和,3.求連續一段格仔的最大值。對於每個2 3操作輸出你所求出的結果。輸入格式 第一行2個整數n,m。接下來一行n個整數表示n個格仔的初始權值。接下來m行,每行3個整數p...

uva11992區間修改線段樹

資料範圍很大,但是可以每行建乙個線段樹,化為線性的 set的優先順序高於add pushdown的時候相當於在add和sett中對乙個整個的區間進行 賦值 一樣,所以還要加上改sum,min1,max1的部分 三個詢問可以一起做。include include include include inc...