树状数组 2 :区间修改,单点查询
给定数列a[1],a[2],…,a[n],你需要依次进行 q 个操作,
操作有两类:
1 l r x:给定 l,r,x对于所有 i∈[l,r]
,将 a[i]加上 x(换言之,将a[l],a[l+1],…,a[r]分别加上 x);
2 i:给定 i,求 a[i]的值。
输入
第一行包含 2 个正整数 n,q表示数列长度和询问个数。保证 1≤n,q≤10^6
第二行 n 个整数a[1],a[2],…,a[n],表示初始数列。保证 ∣a[i]∣≤10^6
接下来 q 行,每行一个操作,为以下两种之一:
1 l r x:对于所有 i∈[l,r],将 a[i]加上 x;
2 i:给定 i,求 a[i]的值。
保证 1≤l≤r≤n,∣x∣≤10^6
输出
对于每个 2 i 操作,输出一行,每行有一个整数,表示所求的结果。
样例
输入复制
3 2
1 2 3
1 1 3 0
2 2
输出复制
2
#include<bits/stdc++.h> #define N 1000005 #define ll long long #define lowbit(x) x&(-x) using namespace std; ll read(ll &x){ ll dat=0,oko=1;char chc=getchar(); while(chc<'0'||chc>'9'){if(chc=='-')oko=-1;chc=getchar();} while(chc<='9'&&chc>='0'){dat=dat*10+chc-'0';chc=getchar();} x=dat*oko;return x; }ll n,m,a[N],b[N],t,x,y,z,opt; void add(ll x,ll k) { while(k<=n) { a[k]+=x; k+=lowbit(k); } }ll ask(ll k) { ll ans=0; while(k>0){ ans+=a[k]; k-=lowbit(k); }return ans; } int main() { read(n),read(m); for(ll i=1;i<=n;i++) { read(b[i]); } for(ll i=1;i<=m;i++) { read(opt),read(x); if(opt==1) { read(y),read(z); add(-z,y+1),add(z,x); //在x这个位置打上标记z,在y+1打上标记-z } if(opt==2)printf("%lld ",b[x]+ask(x)); } return 0; }
树状数组 3 :区间修改,区间查询
1.给[a ,b]整体上加上一个常数c。
2.查询[a ,b]区间的和。
输入
The first line contains two numbers N and Q. 1 ≤ N,Q ≤ 100000.
The second line contains N numbers, the initial values of A1, A2, ... , AN. -1000000000 ≤ Ai ≤ 1000000000.
Each of the next Q lines represents an operation.
"C a b c" means adding c to each of Aa, Aa+1, ... , Ab. -10000 ≤ c ≤ 10000.
"Q a b" means querying the sum of Aa, Aa+1, ... , Ab.
输出
You need to answer all Q commands in order. One answer in a line. The sums may exceed the range of 32-bit integers
样例
输入复制
10 5
1 2 3 4 5 6 7 8 9 10
Q 4 4
Q 1 10
Q 2 4
C 3 6 3
Q 2 4
输出复制
4
55
9
15
注意在维护i*B[i]时,可设exdel(i)=i*b[i]
当我们在区间[L,R]加上V时
exdel(L)=exdel(L)+V*L
exdel(R+1)=exdel(R+1)-V*(R+1)
于是我们按这种方式维护C1数组就好了。
#include<iostream> long long s[100010],n,m; struct node{ long long c[100010]; void add(long long x,long long y) { for(;x<=n;x+=x&-x)c[x]+=y; } long long ask(long long x) { long long ans=0; for(;x;x-=x&-x)ans+=c[x]; return ans; } }c1,c2; int main() { scanf("%lld%lld",&n,&m); for(int i=1;i<=n;i++) { scanf("%lld",s+i); s[i]+=s[i-1]; } for(int i=1;i<=m;i++) { char k[3]; long long a,b,c; scanf("%s",k); if(k[0]=='Q') { scanf("%lld%lld",&a,&b); printf("%lld ",s[b]+(b+1)*c1.ask(b)-c2.ask(b)-s[a-1]-a*c1.ask(a-1)+c2.ask(a-1)); } else { scanf("%lld%lld%lld",&a,&b,&c); c1.add(a,c),c1.add(b+1,-c); c2.add(a,a*c),c2.add(b+1,-(b+1)*c); } } }