BZOJ3155:Preprefix sum(线段树)

Description

Input

第一行给出两个整数N,M。分别表示序列长度和操作个数
接下来一行有N个数,即给定的序列a1,a2,....an
接下来M行,每行对应一个操作,格式见题目描述

Output

对于每个询问操作,输出一行,表示所询问的SSi的值。

Sample Input

5 3
1 2 3 4 5
Query 5
Modify 3 2
Query 5

Sample Output

35
32

HINT

1<=N,M<=100000,且在任意时刻0<=Ai<=100000

Solution

直接用线段树维护一次前缀和的数组$S$,然后修改后缀,查询前缀。注意常数。

Code

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #define N (100009)
 5 #define LL long long
 6 using namespace std;
 7 
 8 struct Sgt{LL val,add;}Segt[N<<2];
 9 int n,m,x,y;
10 LL a[N],S[N];
11 char opt[10];
12 
13 inline int read()
14 {
15     int x=0; char c=getchar();
16     while (c<'0' || c>'9') c=getchar();
17     while (c>='0' && c<='9') x=x*10+c-'0', c=getchar();
18     return x;
19 }
20 
21 void Pushdown(int now,int l,int r)
22 {
23     if (Segt[now].add)
24     {
25         int mid=(l+r)>>1;
26         Segt[now<<1].add+=Segt[now].add;
27         Segt[now<<1|1].add+=Segt[now].add;
28         Segt[now<<1].val+=Segt[now].add*(mid-l+1);
29         Segt[now<<1|1].val+=Segt[now].add*(r-mid);
30         Segt[now].add=0;
31     }
32 }
33 
34 void Update(int now,int l,int r,int l1,int r1,LL k)
35 {
36     if (l>r1|| r<l1) return;
37     if (l1<=l && r<=r1)
38     {
39         Segt[now].add+=k;
40         Segt[now].val+=(r-l+1)*k;
41         return;
42     }
43     int mid=(l+r)>>1; Pushdown(now,l,r);
44     Update(now<<1,l,mid,l1,r1,k);
45     Update(now<<1|1,mid+1,r,l1,r1,k);
46     Segt[now].val=Segt[now<<1].val+Segt[now<<1|1].val;
47 }
48 
49 LL Query(int now,int l,int r,int l1,int r1)
50 {
51     if (l>r1|| r<l1) return 0;
52     if (l1<=l && r<=r1) return Segt[now].val;
53     int mid=(l+r)>>1; Pushdown(now,l,r);
54     return Query(now<<1,l,mid,l1,r1)+Query(now<<1|1,mid+1,r,l1,r1);
55 }
56 
57 int main()
58 {
59     n=read(); m=read();
60     for (int i=1; i<=n; ++i)
61         a[i]=read(), S[i]=S[i-1]+a[i], Update(1,1,n,i,i,S[i]);
62     while (m--)
63     {
64         scanf("%s",&opt); x=read();
65         if (opt[0]=='Q') printf("%lld\n",Query(1,1,n,1,x));
66         else y=read(), Update(1,1,n,x,n,y-a[x]), a[x]=y;
67     }
68 }

猜你喜欢

转载自www.cnblogs.com/refun/p/10361774.html