树状数组 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);
}
}
}