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

Posted hhyx

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了A simple problem with int(区间修改,区间查询相关的知识,希望对你有一定的参考价值。

# 题意

给定长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
",ask(1,l,r));
72         }
73     }
74 }

 

以上是关于A simple problem with int(区间修改,区间查询的主要内容,如果未能解决你的问题,请参考以下文章

poj3468 A Simple Problem with Integers (树状数组做法)

POJ3468A Simple Problem with Integers

线段树专题 POJ3468 A Simple Problem with Integers

A Simple Problem with Integers

A Simple Problem with Integers

POJ 3468 A Simple Problem with Integers