分析



树状数组
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
const int N = 100010;
int n, m;
int a[N];
LL tr1[N];
LL tr2[N];
int lowbit(int x)
{
return x & -x;
}
void add(LL tr[], int x, LL c)
{
for (int i = x; i <= n; i += lowbit(i)) tr[i] += c;
}
LL sum(LL tr[], int x)
{
LL res = 0;
for (int i = x; i; i -= lowbit(i)) res += tr[i];
return res;
}
LL prefix_sum(int x)
{
return sum(tr1, x) * (x + 1) - sum(tr2, x);
}
int main()
{
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i ++ ) scanf("%d", &a[i]);
for (int i = 1; i <= n; i ++ )
{
int b = a[i] - a[i - 1];
add(tr1, i, b);
add(tr2, i, (LL)b * i);
}
while (m -- )
{
char op[2];
int l, r, d;
scanf("%s%d%d", op, &l, &r);
if (*op == 'Q')
{
printf("%lld\n", prefix_sum(r) - prefix_sum(l - 1));
}
else
{
scanf("%d", &d);
add(tr1, l, d), add(tr2, l, l * d);
add(tr1, r + 1, -d), add(tr2, r + 1, (r + 1) * -d);
}
}
return 0;
}
懒标签——线段树做法
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
const int N = 100010;
int n, m;
int w[N];
struct Node
{
int l, r;
LL sum, add;
}tr[N * 4];
void pushup(int u){
tr[u].sum = tr[u << 1].sum + tr[u << 1 | 1].sum;
}
void pushdown(int u){
int left=u<<1;int right=u<<1|1;
if(tr[u].add){
tr[left].add+=tr[u].add;tr[left].sum+=(LL)(tr[left].r-tr[left].l+1)*(tr[u].add);
tr[right].add+=tr[u].add;tr[right].sum+=(LL)(tr[right].r-tr[right].l+1)*(tr[u].add);
tr[u].add=0;
}
}
void build(int u,int l,int r){
if(l==r)tr[u]={l,r,w[l],0};
else{
tr[u]={l,r};
int mid=l+r>>1;
build(u << 1, l, mid), build(u << 1 | 1, mid + 1, r);
pushup(u);
}
}
void modify(int u,int l,int r,int d){
if(tr[u].l>=l&&tr[u].r<=r){
tr[u].sum += (LL)(tr[u].r - tr[u].l + 1) * d;
tr[u].add += d;
}
else{
pushdown(u);
int mid=tr[u].l+tr[u].r>>1;
if(l<=mid)modify(u<<1,l,r,d);
if(r>mid)modify(u<<1|1,l,r,d);
pushup(u);
}
}
LL query(int u,int l,int r){
if(tr[u].l>=l&&tr[u].r<=r)return tr[u].sum;
else{
pushdown(u);
int mid = tr[u].l + tr[u].r >> 1;
LL sum = 0;
if (l <= mid) sum = query(u << 1, l, r);
if (r > mid) sum += query(u << 1 | 1, l, r);
pushup(u);
return sum;
}
}
int main(){
cin >> n >> m;
for(int i=1;i<=n;i++)cin >> w[i];
build(1,1,n);
char op[2];
int l, r, d;
while (m -- )
{
scanf("%s%d%d", op, &l, &r);
if (*op == 'C')
{
scanf("%d", &d);
modify(1, l, r, d);
}
else printf("%lld\n", query(1, l, r));
}
return
}