例題 線段樹

2021-07-14 14:45:12 字數 3218 閱讀 8012

1、

!!!!!注意討論不能建樹的情況

nkoj 1321 數列操作問題

時間限制 : 10000 ms 空間限制 : 165536 kb

問題描述

假設有一列數(1≤i≤n),支援如下兩種操作:

將ak的值加d。(k, d是輸入的數)

輸出as+as+1+…+at。(s, t都是輸入的數,s≤t)

輸入格式

第一行乙個整數n,

第二行為n個整數,表示的初始值≤10000。

第三行為乙個整數m,表示運算元

下接m行,每行描述乙個操作,有如下兩種情況:

add k d (表示將ak加d,1<=k<=n,d為數,d的絕對值不超過10000)

sum s t (表示輸出as+…+at)

輸出格式

對於每乙個sum提問,輸出結果

樣例輸入

5 1 2 3 2 4

5 sum 1 2

sum 1 5

add 1 2

sum 1 2

sum 1 5

樣例輸出

3 12

5 14

提示

m,n<=100000

/* 1、線段樹是通過二分思想建立的一顆表示區間關係的樹形結構.

2、節點數最多2n-1個

*/

#include

#include

using

namespace

std;

const

int need=100003;

struct fytree[need*2];//記錄左右兒子就開2×n

//也可以tree[need*4]i*2表示左兒子,i*2+1表示右兒子;不記左右兒子就開4×n

int a[need];

int tot=0,k,d;

void build(int x,int y)

else

if(x==y) tree[s].val=a[x];

}void add_(int s)

int sum_(int s)

/*再或

int sum_(int s)

*/int main()

build(1,n);

int m;scanf("%d",&m);

string b;

for(int i=1;i<=m;i++)

}

2、

nkoj 1344 人力資源管理

時間限制 : 10000 ms 空間限制 : 65536 kb

問題描述

某公司有n個員工,每個員工有乙個工作能力值(該值為60000以內的自然數)。

tom是公司人力資源部門的主管,他可以進行如下3種操作:

1.tom為公司招聘了乙個能力值為x的新員工

2.tom為公司辭退了乙個能力值為y的員工

3.tom要查出在所有員工能力值由高到低的排名中,能力值大於w的員工的人數

輸入格式

第一行兩個整數n,m 表示有n個員工,和tom的m項工作

接下來一行,n個整數,表示n個員工的能力值

接下來m行,每行有兩個整數a,b(1<=b<=60000)。

a==1 表示招聘了乙個能力值為b的新員工

a==2 表示辭退了乙個能力值為b的員工(若沒有能力值為b的員工,則該操作無效)

a==3 表示查出能力值》b的員工的個數,並輸出結果

輸出格式

若干行,每行乙個整數,表示輸入中所有a==3的操作的結果。

樣例輸入

樣例輸入1:

6 5

9 4 6 2 3 5

1 7

1 10

3 6

2 9

3 6

樣例輸入2:

4 4

4 1 2 5

1 3

3 3

2 4

3 1

樣例輸出

樣例輸出1:

3 2

樣例輸出2:

2 3

提示

n,m<=100000

思路:

1、每個員工的能力值在60000以內,所以建立乙個表示區間[1,60001]的線段樹

2、對於第三類查詢,即為求b+1到max區間中的人數,注意當b+1大於max時直接輸出0;

#include

#include

using namespace std;

const int need1=60003;

const int need2=100003;

struct fyt[need2*2];

struct yfc[need2];

int a[need2];

int tot=0,k,ne=-need1;

void build(int

x,int

y) t[s].le=tot+1;build(x,(x+y)/2);

t[s].ri=tot+1;build((x+y)/2+1,y);

t[s].val=t[t[s].le].val+t[t[s].ri].val;

}void add_(ints)

void fire_(int

s)int cnt(int

s)int main()

for(int i=1;i<=m;i++)

build(1,ne);

for(int i=1;i<=m;i++)

else

if(c[i].mold==1)

else

if(c[i].mold==3) printf("%d\n",k>=ne?0:cnt(1));

}}

線段樹例題

線段樹可以說是每次比賽中必出的題了,但是線段樹好難,我太難了,我上輩子一定是一道線段樹的題。下面是一些基礎線段樹的題目,入門必備。線段樹是一種二叉搜尋樹,將原始資料都存在葉節點,依次表示出每個葉節點的根節點。一般陣列開到葉節點數量的4倍。關於線段樹的例題 hdu1166 敵兵布陣 按照指示來就可以 ...

例題 線段樹 lazy

1 1 lazy思想 對整個結點進行的操作,先在結點上做標記,而並非真正執行,直到根據查詢操作的需要分到下層。2 延遲標記 lazy 如果需要對乙個區間中每乙個葉結點進行操作,我們不妨先別忙著操作,而是在所有大區間上做乙個標記,下一次遇到或要用到時,再進行處理 標記傳遞 達到減少操作次數,提高線段樹...

線段樹 模板 例題

模板 以區間和為例。ll ls ll p ll rs ll p 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 void f ll p,ll ...