3155: Preprefix sum

Posted mjtcn

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了3155: Preprefix sum相关的知识,希望对你有一定的参考价值。

3155: Preprefix sum

https://www.lydsy.com/JudgeOnline/problem.php?id=3155

 

分析:

  区间修改,区间查询,线段树就好了。

  然后,这题有树状数组!

 

代码:

线段树620ms

技术分享图片
 1 /*
 2 一个数修改影响后面的数,使后面的数都增加或者减少多少,所以线段树维护区间和,区间修改  
 3 */
 4 #include<bits/stdc++.h>
 5 using namespace std;
 6 typedef long long LL;
 7 
 8 inline int read() {
 9     int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch==-)f=-1;
10     for (;isdigit(ch);ch=getchar())x=x*10+ch-0;return x*f;
11 }
12 
13 const int N = 100010;
14 
15 #define Root 1,n,1
16 #define lson l,mid,rt<<1
17 #define rson mid+1,r,rt<<1|1
18 
19 LL sum[N<<2],tag[N<<2],a[N],s[N];
20 void pushup(int rt) {
21     sum[rt] = sum[rt<<1] + sum[rt<<1|1];
22 }
23 void pushdown(int rt,int len) {
24     if (tag[rt]) {
25         tag[rt<<1] += tag[rt]; sum[rt<<1] += tag[rt] * 1ll * (len-len/2);
26         tag[rt<<1|1] += tag[rt]; sum[rt<<1|1] += tag[rt] * 1ll * (len/2);
27         tag[rt] = 0; //--忘记1 
28     }
29 }
30 void build(int l,int r,int rt) {
31     if (l == r) {
32         sum[rt] = s[l];
33         return ;
34     }
35     int mid = (l + r) >> 1;
36     build(lson);
37     build(rson);
38     pushup(rt);
39 }
40 void update(int l,int r,int rt,int L,int R,LL val) {
41     if (L <= l && r <= R) {
42         sum[rt] += val*1ll*(r-l+1);tag[rt] += val;
43         return ;
44     }
45     int mid = (l + r) >> 1;
46     pushdown(rt,r-l+1);
47     if (L <= mid) update(lson,L,R,val);
48     if (R > mid)  update(rson,L,R,val);
49     pushup(rt);
50 }
51 LL query(int l,int r,int rt,int L,int R) {
52     if (L <= l && r <= R) {
53         return sum[rt];
54     }
55     int mid = (l + r) >> 1;
56     LL res = 0;
57     pushdown(rt,r-l+1);
58     if (L <= mid) res += query(lson,L,R);
59     if (R > mid)  res += query(rson,L,R);
60     return res;//--忘记2
61 }
62 int main() {
63     int n = read(),m = read();
64     for (int t,i=1; i<=n; ++i) {
65         a[i] = read();
66         s[i] = s[i-1] + a[i];
67     }
68     build(Root);
69     char opt[10];
70     while (m--) {
71         scanf("%s",opt);
72         if (opt[0]==Q) {
73             int p = read();
74             printf("%lld
",query(Root,1,p));
75         }
76         else {
77             int p = read(); LL v = read();
78             update(Root,p,n,v-a[p]);
79             a[p] = v;
80         }
81     }
82     return 0;
83 }
View Code

 

树状数组392ms

技术分享图片
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long LL;
 4 
 5 inline int read() {
 6     int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch==-)f=-1;
 7     for (;isdigit(ch);ch=getchar())x=x*10+ch-0;return x*f;
 8 }
 9 
10 const int N = 100010;
11 LL a[N];
12 
13 struct BIT{
14     int n;LL c1[N],c2[N];
15     void update(int p,LL v) {
16         for (int i=p; i<=n; i+=(i&(-i))) c1[i] += v,c2[i] += 1ll*p*v; // long long
17     }
18     LL query(int p) {
19         LL ans = 0;
20         for (int i=p; i; i-=(i&(-i))) ans += 1ll*(p+1)*c1[i]-c2[i];
21         return ans;
22     }
23 }bit;
24 
25 int main() {
26     int n = read(),m = read();
27     bit.n = n;  // ---
28     for (int i=1; i<=n; ++i) {
29         a[i] = read();
30         bit.update(i,a[i]);
31     }
32     char opt[10];
33     while (m--) {
34         scanf("%s",opt);
35         if (opt[0]==Q) {
36             int p = read();
37             printf("%lld
",bit.query(p));
38         }
39         else {
40             int p = read(); LL v = read();
41             bit.update(p,v-a[p]);
42             a[p] = v;
43         }
44     }
45     return 0;
46 }
View Code

 

以上是关于3155: Preprefix sum的主要内容,如果未能解决你的问题,请参考以下文章

[bzoj3155]Preprefix sum(树状数组)

BZOJ 3155 Preprefix sum

bzoj3155: Preprefix sum

BZOJ3155: Preprefix sum

BZOJ3155: Preprefix sum

差分+树状数组p4868Preprefix sum