線段樹(模板題)

2021-09-20 21:07:03 字數 4670 閱讀 8643

對於一條數鏈,二分,然後二分,然後再二分…

給定一數列,規定有兩種操作,一是修改某個元素,二是求區間的連續和。(數列元素初始化為0)

【輸入】

輸入資料第一行包含兩個正整數n,m(n≤100000,m≤500000),以下是m行,

每行有三個正整數k,a,b(k=0或1,a,b≤n).k=0時表示將a處數字加上b,k=1時表示詢問 區間[a,b]內所有數的和。

【輸出】

對於每個詢問輸出對應的答案。

【輸入樣例】

10 20

0 1 10

1 1 4

0 6 6

1 4 10

1 8 9

1 4 9

0 10 2

1 1 8

0 2 10

1 3 9

0 7 8

0 3 10

0 1 1

1 3 8

1 6 9

0 5 5

1 1 8

0 4 2

1 2 8

0 1 1

【輸出樣例】
1060

616624

1450

41

#include

#include

using

namespace std;

const

int n=

100005

;int i,j,k;

intread()

while

(ch>=

'0'&&ch<=

'9')

return s*f;

}int n,m;

long

long c[n*4]

,a[n]

;void

update

(int k,

int l,

int r,

int x,

int y)

int mid=

(l+r)

>>1;

update

(k*2

,l,mid,x,y)

;update

(k*2+1

,mid+

1,r,x,y)

; c[k]

=c[k*2]

+c[k*2+

1];}

long

long

query

(int k,

int l,

int r,

int x,

int y)

//在區間a[l]~a[r]中查詢a[x]~a[y]的區間和

intmain()

return0;

}

區間修改區間求和

描述如題,已知乙個數列,你需要進行下面兩種操作:(初始化不為0)

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 51 5 4 2 3

2 2 4

1 2 3 2

2 3 4

1 1 5 1

2 1 4

樣例輸出 [複製]118

20提示

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

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

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

#include

//標程

#include

#define maxn 1000001

#define ll long long

using

namespace std;

unsigned ll n,m,a[maxn]

,ans[maxn<<2]

,tag[maxn<<2]

;inline ll ls

(ll x)

inline ll rs

(ll x)

void

scan()

inline

void

push_up

(ll p)

void

build

(ll p,ll l,ll r)

ll mid=

(l+r)

>>1;

build(ls

(p),l,mid)

;build(rs

(p),mid+

1,r)

;push_up

(p);

}inline

void

f(ll p,ll l,ll r,ll k)

inline

void

push_down

(ll p,ll l,ll r)

inline

void

update

(ll nl,ll nr,ll l,ll r,ll p,ll k)

push_down

(p,l,r)

; ll mid=

(l+r)

>>1;

if(nl<=mid)

update

(nl,nr,l,mid,

ls(p)

,k);

if(nr>mid)

update

(nl,nr,mid+

1,r,

rs(p)

,k);

push_up

(p);

}ll query

(ll q_x,ll q_y,ll l,ll r,ll p)

intmain()

case2:

}}return0;

}

#include

//修正

using

namespace std;

#define mid (t[p].l+t[p].r>>1)

const

int n=

1e5+5;

struct fjyt[n<<2]

;//線段樹大小開4*n

long

long a[n]

;inline

long

longlc(

long

long x)

inline

long

longrc(

long

long x)

long

long

read1()

while

(isdigit

(ch)

)return s*f;

}long

long

read2()

while

(ch>=

'0'&&ch<=

'9')

return s*f;

}void

pushup

(int p)

void

pushnow

(int p,

long

long v)

void

pushdown

(int p)

void

build

(int p,

int l,

int r)

build(lc

(p),l,mid)

,build(rc

(p),mid+

1,r)

; t[p]

.sum=t[

lc(p)

].sum+t[

rc(p)

].sum;

}void

update

(int p,

int ql,

int qr,

long

long v)

if(t[p]

.l>=ql&&t[p]

.r<=qr)

pushdown

(p);

if(ql<=mid)

update(lc

(p),ql,qr,v);if

(qr>mid)

update(rc

(p),ql,qr,v)

;pushup

(p);

}long

long

query

(int p,

int ql,

int qr)

int n,m,juge,k,x,y;

intmain()

else

printf

("%lld\n"

,query(1

,x,y));

}return0;

}

錯誤總結:

線段樹 模板題

problem description 已知乙個數列,你需要進行下面兩種操作 1.將某區間每乙個數加上x 2.求出某區間每乙個數的和 input 第一行包含兩個整數n m,分別表示該數列數字的個數和操作的總個數。第二行包含n個用空格分隔的整數,其中第i個數字表示數列第i項的初始值。接下來m行每行包含...

線段樹之模板題

關於線段樹 首先應該是建樹 c國的死對頭a國這段時間正在進行軍事演習,所以c國間諜頭子derek和他手下tidy又開始忙乎了。a國在海岸線沿直線布置了n個工兵營地,derek和tidy的任務就是要監視這些工兵營地的活動情況。由於採取了某種先進的監測手段,所以每個工兵營地的人數c國都掌握的一清二楚,每...

線段樹 單點更新模板題

線段樹應該是資料結構中的一種吧,說白了,他就是一種工具,只要你學會了他,那麼你就可以在以後的學習中去用它。他的大致用法,就是把乙個一維陣列改變成乙個樹的結構,而且這個樹還是乙個完全二叉樹 上述圖就是把乙個1 8的區間變成了乙個二叉樹的結構,為什麼我們要這樣幹呢?這怎麼說呢?其實我也說不清楚。因為能力...