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 }

 

转载于:https://www.cnblogs.com/fzl194/p/9320637.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值