树状数组 区间修改 单点查询

说一下差分:

现在我们有一个从小到大的数列a[]

a 1 3 6 8 9

然后还有一个差分数组b[]

b 1 2 3 2 1           对应:   1,3-1,6-3,8-6,9-8,

相信某些同学绝已经看出端倪了..这里b[i]=a[i]-a[i-1],我令a[0]=0,故b[1]=a[1]。

int now=0,temp;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&temp);
        update(i,temp-now);
        now=temp;
    }

A数组中的8等于B数组 前4项的和;同理:A 数组中的6  等于B数组中前3项的和,于是单点查询变成了 B 数组的BIT 求和问题,用模版即可!

然后把差分后的序列扔到树状数组里:

#include 
#include 

using namespace std;
int tree[500005];
int n,m;
int lowbit(int i)
{
    return i&(-i);
}
void update(int i,int x)
{
    while(i<=n)
    {
        tree[i]+=x;
        i+=lowbit(i);
    }
}
int query(int i)
{
    int sum=0;
    while(i>0)
    {
        sum+=tree[i];
        i-=lowbit(i);
    }
    return sum;
}
int main()
{
    int now=0,temp;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&temp);
        update(i,temp-now);
        now=temp;
    }
    while(m--)
    {
        int t,x,y,k;
        scanf("%d",&t);
        if(t==1)
        {
            scanf("%d%d%d",&x,&y,&k);
            update(x,k);
            update(y+1,-k);
        }
        else
        {
            scanf("%d",&k);
            printf("%d\n",query(k));
        }
    }
    return 0;
}

 

你可能感兴趣的:(acm,cpp)