題目鏈結
題意就不再多囉嗦了,這道題目是樹狀陣列模板題目,也是我的第乙個樹狀陣列題目。就說一下一開始我的錯誤之處,我是直接輸入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國在海岸線沿...