HDU1166 敵兵布陣 樹狀陣列 線段樹

2021-08-04 09:54:40 字數 1735 閱讀 4069

題目鏈結

題意就不再多囉嗦了,這道題目是樹狀陣列模板題目,也是我的第乙個樹狀陣列題目。就說一下一開始我的錯誤之處,我是直接輸入a[i]的,而不是通過add()生成a[i],所以在後期求和的時候總是求不對。正確的做法應該是通過add(i,val)生成a[i],這個,在管理第i的節點的以後的節點都會加上val,因為在求和的時候計算的就是從i節點以下各個節點的管理節點,所以一開始要通過add()把每個節點的值加到它的管理節點上來。

附一篇講的不錯的樹狀陣列講解

ac**如下:

#include #include using namespace std;

int t,n,a[50005],l,r,num,cas=0,val;

char str[10];

int lowbit(int k)

void add(int k, int num)

}void sub(int k, int num)

}int read(int k)

return sum;

}int main()

printf("case %d:\n",++cas);

while(1)

else if(str[0] == 's')

else if(str[0] == 'q')

else

break;

} }return 0;

}

線段樹解法:單點更新查詢即可,

附線段樹講解部落格:

ac**如下:

#include #include #include using namespace std;

const int maxn = 5e4 + 5;

int sum[maxn << 2],add[maxn << 2];

int a[maxn],n,t,cas = 0;

void pushup(int rt)

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

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

build(l,m,rt << 1); //分別構建左右子樹

build(m+1,r,rt << 1 | 1);

pushup(rt); //更新當前節點值

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

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

if(l <= m) update(l,c,l,m,rt << 1); //判斷要更新的點在左子樹還是右子樹

else update(l,c,m+1,r,rt << 1 | 1);

pushup(rt); //遞迴結束時向上更新其父節點

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

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

int ans = 0;

if(l <= m) ans += query(l,r,l,m,rt << 1); //有交叉則繼續遞迴查詢

if(r > m) ans += query(l,r,m+1,r,rt << 1 | 1);

return ans;

}int main()

else if(str[0] == 's')

else

} }return 0;

}

HDU 1166 敵兵布陣 樹狀陣列

用樹狀陣列很簡單,太晚了,貼下 睡覺去。另,研究線段樹的時候,發現網上流傳著有幾種不同的線段樹,最正宗的是以單位區間為單位,只能處理線段 另外還有幾種葉子結點是點的,這種也可以用來處理點,所以這題是可以用這種線段樹做的。還搞不太清楚它們之間的關係。mark一下,明天再說。include includ...

HDU 1166 敵兵布陣 樹狀陣列

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

HDU 1166 敵兵布陣 (樹狀陣列)

敵兵布陣 time limit 1000msmemory limit 32768kb64bit io format i64d i64u submit status description c國的死對頭a國這段時間正在進行軍事演習,所以c國間諜頭子derek和他手下tidy又開始忙乎了。a國在海岸線沿...