洛谷 P3368 树状数组 题解

题面

本题随便看两眼就知道该题满足了优美的查分性质;

对于在区间[x,y]内操作时,应该将查分数组的第x项和第y+1项进行相反操作;

询问答案时,问第i个数的值就是查分数组的前i项和;

暴力+玄学卡常可以A掉数据十分水的数据;

正解是求前i项和的时候用树状数组来维护;

#include <bits/stdc++.h>
using namespace std;
int n,m;
int a[500010];
int b[500010];
int sum[50000010];
int lowbit(int x)
{
    return x&(-x);
}
void add(int x,int v)
{
    while(x<=n){
        sum[x]+=v;
        x+=lowbit(x);
    }
}
int read(int x)
{
    int res=0;
    while(x>0){
        res+=sum[x];
        x-=lowbit(x);
    }
    return res;
}
int main ()
{
    cin>>n>>m;
    for(register int i=1;i<=n;i++){
        scanf("%d",&a[i]);
        b[i]=a[i]-a[i-1];
        add(i,b[i]);
    }
    for(register int i=1;i<=m;i++){
        int opt;
        cin>>opt;
        if(opt==1)
        {
            int x,y,k;
            scanf("%d%d%d",&x,&y,&k);
            add(x,k);
            add(y+1,-k);
            b[x]+=k;
            b[y+1]-=k;
        }
        else{
            int x;
            scanf("%d",&x);
            cout<<read(x)<<endl;
        }
    }
}
原文地址:https://www.cnblogs.com/kamimxr/p/11288833.html