線段樹 單點修改

2021-09-25 06:16:39 字數 1599 閱讀 2369

洛谷p3347

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

1.將某乙個數加上x

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

輸入格式:

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

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

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

操作1: 格式:1 x k 含義:將第x個數加上k

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

輸出格式:

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

輸入樣例#1:複製

5 5

1 5 4 2 3

1 1 3

2 2 5

1 3 -1

1 4 2

2 1 4

輸出樣例#1:複製

14

16

時空限制:1000ms,128m

資料規模:

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

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

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

樣例說明:

故輸出結果14、16

#includeusing namespace std;

int n,m,d[501000];

struct nodet[501000*4];//注意:這裡為什麼要開四倍空間

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

int mid=(l+r)/2;

build(k*2,l,mid);

build(k*2+1,mid+1,r);//思考:為什麼左子樹的編號是k*2,右子樹的編號是k*2+1;

t[k].sum=t[k*2].sum+t[k*2+1].sum;

} //建立線段樹

void update(int k,int pos,int w)

int mid=(t[k].l+t[k].r)/2;

if(pos<=mid) update(k*2,pos,w);//如果目標位置在左子樹中

if(mid

t[k].sum=t[k*2].sum+t[k*2+1].sum;//子樹中的節點改變 那麼相應的改變父親節點的區間和

} int ask(int k,int l,int r)

int mid=(t[k].l+t[k].r)/2,ans=0;

if(l<=mid)ans+=ask(k*2,l,r);//左子樹中 包含目標區間的 點

if(mid

return ans;

}int main()

if(op==2)

} return 0;

}

線段樹 建樹 單點修改 單點 區間查詢

線段樹 sgement tree 是一種分治思想的二叉樹結構,用於在區間上進行資訊統計。與按照二進位制位進行區間劃分的樹狀陣列相比,線段樹是一種更加通用的結構 1.線段樹的每個節點都代表乙個區間。2.線段樹具有唯一的根節點,代表的區間是整個統計範圍,如 1,n 3.線段樹的每個葉節點都代表乙個長度為...

操作格仔 單點修改線段樹

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

線段樹單點修改區間查詢

這是一道模板題。給定數列 a 1 a 2 a n 你需要依次進行 qq 個操作,操作有兩類 1 i x 給定 i,x,將 a i 加上 x 2 l r 給定 l,r,求 ri la i 的值 換言之,求 a l a l 1 a r 的值 input 第一行包含 2 個正整數 n,q,表示數列長度和詢...