Codevs1082 线段树练习三(树状数组)
2017-08-29 22:02
309 查看
终于抽出时间学了一发树状数组的区间修改
用c[i]=a[i]−a[i−1]
很容易得到:a[i]=∑i=1ci
s[i]=(i−1)⋅c[i]
那么到n的答案为
ans=(n−1)⋅∑i=1ci−∑i=1si
用c[i]=a[i]−a[i−1]
很容易得到:a[i]=∑i=1ci
s[i]=(i−1)⋅c[i]
那么到n的答案为
ans=(n−1)⋅∑i=1ci−∑i=1si
e858 #include<iostream> #include<cstdio> #include<cmath> #include<cstring> #include<algorithm> #define fo(i,a,b) for(int i=a;i<=b;i++) #define fod(i,a,b) for(int i=a;i>=b;i--) using namespace std; typedef long long ll; const int N=2e5+10; int n,m; ll delta ,deltai ,sum ,a ; #define lowbit(x) ((x)&(-x)) ll query(ll *array,int pos) { ll temp = 0ll; while(pos > 0) { temp += array[pos]; pos -= lowbit(pos); } return temp; } void update(ll *array,int pos,int x) { while(pos <= N) { array[pos] += x; pos += lowbit(pos); } } int main() { scanf("%d",&n); fo(i,1,n) {scanf("%lld",&a[i]);sum[i]=sum[i-1]+a[i];} scanf("%d",&m); for(int op,l,r,x,i=1;i<=m;i++) { scanf("%d",&op); if(op==1) { scanf("%d%d%d",&l,&r,&x); update(delta,l,x); update(delta,r+1,-x); update(deltai,l,x*l); update(deltai,r+1,-x*(r+1)); } else { scanf("%d%d",&l,&r); ll suml=sum[l-1]+l*query(delta,l-1)-query(deltai,l-1); ll sumr=sum[r]+(r+1)*query(delta,r)-query(deltai,r); printf("%lld\n",sumr-suml); } } return 0; }
相关文章推荐
- 【CODE[VS]】1082 线段树练习 3 树状数组
- 【codevs1082】线段树练习3——树状数组(改段求段)
- codevs 1082 线段树练习 3 区间更新+延迟标记
- Code Vs 1082 线段树练习 3
- 【codevs 1080~1082】线段树练习重做
- COdeVS——T 1082 线段树练习 3 (分块练习)
- codevs 1080 线段树练习--用树状数组做的
- 【codevs 1080~1082】线段树练习重做
- 【数据结构】树状数组模板--CODE[VS] 1080线段树练习and1081线段树练习2
- [CODEVS1082]线段树练习 3
- 【CODEVS1082】线段树练习3
- codevs 1082 线段树练习 3(区间维护)
- 【codevs1082】线段树练习 3
- Codevs1082 线段树练习 3 Lazy
- 【codevs1082】线段树练习3 线段树
- <线段树系列2> codevs 1082 线段树练习2
- [Codevs] 1082 线段树练习3
- <线段树系列3> codevs 1082 线段树练习3
- codevs 1082 线段树练习 3
- codevs1080线段树练习(树状数组)