ZOJ-3279 Ants 树状数组 + 二分
题目链接:
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 }
越努力,越幸运