HDU 1166 敵兵布陣(線段樹)

2021-07-04 14:38:03 字數 1624 閱讀 1767

這是第二次寫這道題的題解了,上次是用樹狀陣列寫的。

後來發現自己的想法實在是太幼稚了,雖說樹狀陣列的題都可以用線段樹做,但並不是所有能用線段樹做的題目都可以用樹狀陣列,沒辦法,還是的硬著 頭皮開始啃線段樹,那麼還是從敵兵布陣這道題開始吧 ……

線段樹是乙個非常高效的資料結構。 所有能用樹狀陣列解決的問題都可以用線段樹解決。 線段樹是用乙個陣列來維護被處理陣列的資訊。 複雜度是log級別的。 這裡對於原始陣列用a表示, 維護陣列用sum表示。sum陣列下標從1開始。對於當前節點rt的左孩子和有孩子分別為rt<<1, rt<<1 | 1 。常見的線段樹的功能是實現點修改區間查詢、區間修改點查詢、區間修改區間查詢等等。

這道題呢,意思也很明顯,就是線段樹的單點更新,線段樹一般變化最大的就是詢問,和更新。

在這裡,我還學習了大牛們得巨集定義寫法:

#define lson l,m,rt<<1

#define rson m+1,r,rt<<1|1

#define root 1,n,1

題目ac **如下:

/*

author:zxpxx

memory: 2136 kb time: 358 ms

language: c++ result: accepted

*/#include #include #include using namespace std;

const int maxn=50000+5;

#define lson l,m,rt<<1

#define rson m+1,r,(rt<<1)+1

#define root 1,n,1

int s[maxn*4];

void push_up(int rt)

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

int m = (l + r) >> 1;

build(lson);

build(rson);

push_up(rt);

}void update(int x, int d, int l, int r, int rt)

int m = (l + r) >> 1;

if(x <= m) update(x, d, lson);

else update(x, d, rson);

push_up(rt);

}int query(int l, int r, int l, int r, int rt)

int m = (l + r) >> 1;

int ret=0;

if(l<=m)

ret += query(l,r,lson);

if(r>m)

ret += query(l,r,rson);

return ret;

}int main() else if(str[0]=='a') else if(str[0]=='s') }}

return 0;

}

線段樹算是比較難的演算法之一了,但是適用範圍很廣,還是要認真學一下的。還有,線段樹對遞迴要求有點高,遞迴不是很熟的同學,最好去把遞迴複習幾遍,當然也包括鄙人自己這個患有「遞迴恐懼症」的啦……╮(╯▽╰)╭……

HDU 1166 敵兵布陣 線段樹

第一道線段樹的題目,正在學習中 include include include using namespace std define max 55555 int sum max 2 n void pushup int rt void build int l,int r,int rt int mid ...

hdu1166敵兵布陣 線段樹

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

A 敵兵布陣 線段樹 hdu 1166

a 敵兵布陣 time limit 1000ms memory limit 32768kb 64bit io format i64d i64u submit status practice hdu 1166 description c國的死對頭a國這段時間正在進行軍事演習,所以c國間諜頭子derek...