1. 程式人生 > >ZOJ-3279 Ants 樹狀數組 + 二分

ZOJ-3279 Ants 樹狀數組 + 二分

char 前綴 owb ons 修改 using print tps clu

題目鏈接:

https://cn.vjudge.net/problem/ZOJ-3279

題目大意:

有1到n 那個level 每一個level有a[i]只螞蟻
兩種操作

p a b 把第a個level的螞蟻數量改成b

q a 查詢第a只螞蟻在哪個level裏。

解題思路:

用樹狀數組動態維護前綴和,二分查找第a個螞蟻即可

要用printf,不然會超時

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn = 1e5 + 10;
 4 int tree[maxn], n, a[maxn];
 5 int lowbit(int
x) 6 { 7 return (x & (-x)); 8 } 9 void add(int x, int d)//將x下標的值加上d 10 { 11 while(x <= n) 12 { 13 tree[x] += d; 14 x += lowbit(x); 15 } 16 } 17 int sum(int x) 18 { 19 int tot = 0; 20 while(x) 21 { 22 tot += tree[x]; 23 x -= lowbit(x);
24 } 25 return tot; 26 } 27 28 int main() 29 { 30 while(scanf("%d", &n) != EOF) 31 { 32 memset(a, 0, sizeof(a)); 33 memset(tree, 0, sizeof(tree)); 34 for(int i = 1; i <= n; i++) 35 { 36 scanf("%d", &a[i]); 37 add(i, a[i]);
38 } 39 int m, x, y; 40 scanf("%d", &m); 41 char s[2]; 42 while(m--) 43 { 44 scanf("%s", s); 45 if(s[0] == p) 46 { 47 scanf("%d%d", &x, &y); 48 add(x, -a[x]);//單點修改 49 add(x, y); 50 a[x] = y; 51 } 52 else if(s[0] == q) 53 { 54 scanf("%d", &x); 55 int l = 1, r = n, ans; 56 while(l <= r) 57 { 58 int m = (l + r) / 2; 59 if(sum(m) >= x)ans = m, r = m - 1; 60 else l = m + 1; 61 } 62 printf("%d\n", ans); 63 } 64 } 65 } 66 return 0; 67 }

ZOJ-3279 Ants 樹狀數組 + 二分