原题链接:A Simple Problem with Integers
题意:给定一个数列A[1],A[2]...A[N]以及Q个操作,按顺序行这些操作,操作分为两种:/*
用树状数组实现,复杂度是Q*lg(N)
对区间[l,r]同时加上x:令s(i)为加x之前的和,s'(i)为加x之后的和
1. i
#include
using namespace std;
const int MAX_N = 100001;
const int MAX_Q = 100001;
typedef long long ll;
//输入数据
int N, Q;
int A[MAX_N];
char T[MAX_Q];
int L[MAX_Q], R[MAX_Q], X[MAX_Q];
//BIT树状数组
ll bit0[MAX_N + 1], bit1[MAX_N + 1];
ll sum(ll *b, int i){ //sum(bit, i)是树状数组bit的前i项和
ll s = 0;
while(i > 0){
s += b[i];
i -= i & -i;
}
return s;
}
void add(ll *b, int i, int v){ //i位置上加v
while(i <= N){
b[i] += v;
i += i & -i;
}
}
void solve(){
for(int i = 1;i <= N;i ++){
add(bit0, i, A[i]);
}
for(int i = 1;i <= Q;i ++){
if(T[i] == 'C'){
add(bit0, L[i], -X[i] * (L[i] - 1));
add(bit1, L[i], X[i]);
add(bit0, R[i] + 1, X[i] * R[i]);
add(bit1, R[i] + 1, -X[i]);
}else{
ll res = 0;
res += sum(bit0, R[i]) + sum(bit1, R[i]) * R[i];
res -= sum(bit0, L[i] - 1) + sum(bit1, L[i] - 1) * (L[i] - 1);
printf("%lld\n", res);
}
}
}
int main(){
scanf("%d%d", &N, &Q);
for(int i = 1;i <= N;i ++)
scanf("%d", &A[i]);
for(int i = 1;i <= Q;i ++){
scanf(" %c", &T[i]);
if(T[i] == 'C')
scanf("%d%d%d", &L[i], &R[i], &X[i]);
else
scanf("%d%d", &L[i], &R[i]);
}
solve();
return 0;
}
//用线段树实现,复杂度Q*lgN
#include
#include
using namespace std;
typedef long long ll;
const int MAX_N = 100001;
const int MAX_Q = 100001;
const int DAT_SIZE = (1 << 18) - 1;
//输入数据
int N, Q;
int A[MAX_N];
char T[MAX_Q];
int L[MAX_Q], R[MAX_Q], X[MAX_Q];
//线段树
ll data[DAT_SIZE]; //data[i]:第i个节点对应的区间的所有元素共同加上的值
ll datb[DAT_SIZE]; //datb[i]:第i个节点对应的区间除去data[i]之外的其他值得和
//对区间[a,b)同时加x,k是节点的编号,对应的区间[l,r)
void add(int a, int b, int x, int k, int l, int r){
if(a <= l && b >= r){ //[a,b)包含[l,r)
data[k] += x;
}else if(l < b && r > a){ // [a,b)与[l,r)有交集(l l && r > a)
ll res = (min(b, r) - max(a, l)) * data[k];
int mid = (l + r) / 2;
res += sum(a, b, k * 2 + 1, l, mid);
res += sum(a, b, k * 2 + 2, mid, r);
return res;
}
}
void solve(){
for(int i = 0;i < N;i ++){ //起点从0开始
add(i, i + 1, A[i], 0, 0, N);
}
for(int i = 0;i < Q;i ++){
if(T[i] == 'C'){
add(L[i] - 1, R[i], X[i], 0, 0, N); //加
}else {
printf("%lld\n", sum(L[i] - 1, R[i], 0, 0, N)); //求和
}
}
}
int main(){
scanf("%d%d", &N, &Q);
for(int i = 0;i < N;i ++)
scanf("%d", &A[i]);
for(int i = 0;i < Q;i ++){
scanf(" %c", &T[i]);
if(T[i] == 'C')
scanf("%d%d%d", &L[i], &R[i], &X[i]);
else
scanf("%d%d", &L[i], &R[i]);
}
solve();
return 0;
}