BZOJ3212 Pku3468 A Simple Problem with Integers 题解

题目大意

  一个数列,有两个操作:1.修改操作,将一段区间内的数加上c;2.查询操作,查询一段区间内的数的和。

思路:

  线段树裸题,区间修改、区间查询,维护和以及加上的数,由于无序,不需要向下推标记,只需在子树更新完之后更新根节点即可。

代码:

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 using namespace std;
 5 
 6 long long sum[400001],mor[400001];
 7 
 8 void up(int cur,int t)
 9 {
10     sum[cur]=sum[cur<<1]+sum[cur<<1|1]+t*mor[cur];
11 }
12 
13 void add(int L,int R,int l,int r,int x,int cur)
14 {
15     if (L>=l && R<=r)
16     {
17         mor[cur]+=x;
18         sum[cur]+=(R-L+1)*x;
19         return;
20     }
21     int mid=L+R>>1;
22     if (l<=mid) add(L,mid,l,r,x,cur<<1);
23     if (r>mid) add(mid+1,R,l,r,x,cur<<1|1);
24     up(cur,R-L+1);
25 }
26 
27 long long ask(int L,int R,int l,int r,int cur)
28 {
29     if (L>=l && R<=r) return sum[cur];
30     int mid=L+R>>1;
31     long long ans=mor[cur]*(r-l+1);
32     if (l<=mid) ans+=ask(L,mid,l,min(mid,r),cur<<1);
33     if (r>mid) ans+=ask(mid+1,R,max(l,mid+1),r,cur<<1|1);
34     return ans;
35 }
36 
37 int main()
38 {
39     int n,m,i,a,b,c;
40     scanf("%d%d",&n,&m);
41     for (i=1;i<=n;i++) scanf("%d",&a),add(1,n,i,i,a,1);
42     for (i=1;i<=m;i++)
43     {
44         char ch=getchar();
45         while (ch<'A' || ch>'Z') ch=getchar();
46         if (ch=='Q') scanf("%d%d",&a,&b),printf("%lld\n",ask(1,n,a,b,1));
47         else scanf("%d%d%d",&a,&b,&c),add(1,n,a,b,c,1);
48     }
49     return 0;
50 }

 

转载于:https://www.cnblogs.com/HHshy/p/5733920.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值