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 }
树状数组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 }
以上是关于3155: Preprefix sum的主要内容,如果未能解决你的问题,请参考以下文章