码迷,mamicode.com
首页 > 其他好文 > 详细

A simple problem with int(区间修改,区间查询

时间:2020-03-14 01:25:36      阅读:53      评论:0      收藏:0      [点我收藏+]

标签:node   char   namespace   amp   while   style   imp   auto   std   

# 题意

给定长n的原数组,m个操作每个操作有两种

1)C l r d 将区间[l~r]加上d

2)Q l r 询问区间[l~r]的和

# 题解

操作有区间操作,所以需要延迟标记来记录区间的变化以达到O(logN)的复杂度

每个标记记录子节点的变化

每次分裂的时候要先将左右的标记更新

 

 1 #include<bits/stdc++.h>
 2 #define ll long long
 3 using namespace std;
 4 const int N=1e5+10;
 5 int a[N];
 6 int n,m;
 7 struct node {
 8     int l,r;
 9     ll sum,add;
10 }tr[N*4];
11 void pushup(int u){
12     tr[u].sum = tr[u<<1].sum+tr[u<<1|1].sum;
13 }
14 void pushdown(int u){
15     auto &root=tr[u],&left=tr[u<<1],&right=tr[u<<1|1];
16     if(root.add){
17         left.add+=root.add;
18         left.sum+=(ll)(left.r-left.l+1)*root.add;
19         right.add+=root.add;
20         right.sum+=(ll)(right.r-right.l+1)*root.add;
21         root.add=0;
22     }
23 }
24 void build(int u,int l,int r){
25     if(l == r){
26         tr[u]={l,l,a[l],0};
27         return;
28     }
29     tr[u].l=l,tr[u].r=r;
30     int mid=l+r>>1;
31     build(u<<1,l,mid);
32     build(u<<1|1,mid+1,r);
33     pushup(u);
34 }
35 void change(int u,int l,int r,int d){
36     if(tr[u].l>=l && tr[u].r<=r){
37         tr[u].sum+=(ll)(tr[u].r-tr[u].l+1)*d;
38         tr[u].add+=d;//当前结点更新了左右未更新
39         return;
40     }
41     pushdown(u);//接下来求左右所以先把左右的延迟标记改一下
42     int mid=tr[u].l+tr[u].r>>1;
43     if(l<=mid) change(u<<1,l,r,d);
44     if(r>mid) change(u<<1|1,l,r,d);
45     pushup(u);
46 }
47 ll ask(int u,int l,int r){
48     if(tr[u].l>=l && tr[u].r<=r)
49         return tr[u].sum;
50     pushdown(u);//分裂,更改左右的延迟标记
51     int mid=tr[u].l+tr[u].r>>1;
52     ll sum=0;
53     if(l<=mid) sum+=ask(u<<1,l,r);
54     if(r>mid) sum+=ask(u<<1|1,l,r);
55     return sum;
56 }
57 int main(){
58     scanf("%d%d",&n,&m);
59     for(int i=1;i<=n;i++)
60         scanf("%d",&a[i]);
61     build(1,1,n);
62     int l,r,d;
63     char op[2];
64     while(m--){
65         scanf("%s%d%d",op,&l,&r);
66         if(op[0]==C){
67             scanf("%d",&d);
68             change(1,l,r,d);
69         }
70         else{
71             printf("%lld\n",ask(1,l,r));
72         }
73     }
74 }

 

A simple problem with int(区间修改,区间查询

标签:node   char   namespace   amp   while   style   imp   auto   std   

原文地址:https://www.cnblogs.com/hhyx/p/12489915.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!