樹狀數組

樹狀數組模板

樹狀數組的應用:

  • 單點更新-區間查詢
  • 區間更新-單點查詢
  • 區間更新-區間查詢

一、單點更新-區間查詢

題目鏈接:NYO116 士兵殺敵(二)
題目描述

代碼:


#include<cstdio>
#include<cstring>
int sum[2000000+2];
int n,m;

 inline int lowerbit(int x)
{
    return x&-x;
    //return x-(x&(x-1));
}

void UpDate(int x,int y)
{
    while(x<=n)
    {
        sum[x]+=y;
        x+=lowerbit(x);
    }
}
int  query(int x)
{
    int ans=0;
    while(x>0)
    {
        ans+=sum[x];
        x-=lowerbit(x);
    }
    return ans;
}
int main()
{
    memset(sum,0,sizeof(sum));
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
    {
        int t;
        scanf("%d",&t);
        UpDate(i,t);
    }
    char str[10];
    int l,r;
    while(m--)
    {
        scanf("%s%d%d",&str,&l,&r);
        if(str[0]=='Q')
        {
            printf("%d\n",query(r)-query(l-1));
        }
        else
        {
            UpDate(l,r);
        }   
    }
    return 0;
}        


二、區間更新-單點查詢

題目鏈接:HDU1556 Color the ball
題目描述
代碼:


//差分數組的理解

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;

const int MAXN=100010;
int c[MAXN];
int n;

int lowbit(int x)
{
    return x&(-x);
}
void addd(int i,int val)
{
    while(i<=n)
    {
        c[i]+=val;
        i+=lowbit(i);
    }
}
int sum(int i)
{
    int s=0;
    while(i>0)
    {
        s+=c[i];
        i-=lowbit(i);
    }
    return s;
}
int main()
{
    int l,r;
    while(scanf("%d",&n),n)
    {
        memset(c,0,sizeof(c));
        for(int i=0;i<n;i++)
        {
            scanf("%d%d",&l,&r);
            add(l,1);
            add(r+1,-1);
        }
        for(int i=1;i<n;i++)
          printf("%d ",sum(i));
        printf("%d\n",sum(n));
    }
    return 0;
}


三、區間更新-區間查詢

題目鏈接:POJ 3468 A Simple Problem with Integers
題目描述
代碼:


#include<cstdio>
#include<cstring> 
#define ll long long int
#define lowerbit(x) (x&-x)
const int maxn=100000+5; 
int n,q;
ll sum[maxn];//原始數組前綴和 
ll c1[maxn],c2[maxn];
void add(int i,int x)
{
    int pos=i;
    while(pos<=n)
    {
        c1[pos]+=x;
        c2[pos]+=i*x;
        pos+=lowerbit(pos);
    }
}
ll query(ll x)
{
    ll ans=0;
    int i=x;
    while(i>0)
    {
        ans+=(x+1)*c1[i]-c2[i];
        i-=lowerbit(i);
    }
    return ans;
}
int main()
{
    scanf("%d%d",&n,&q);
    memset(sum,0,sizeof(sum));
    memset(c1,0,sizeof(c1));
    memset(c2,0,sizeof(c2));
    for(int i=1;i<=n;i++)
    {
        ll t;
        scanf("%lld",&t);
        sum[i]=sum[i-1]+t; 
    }
     char str[4];
     int l,r,p;
    for(int i=0;i<q;i++)
    {
        scanf("%s",str);
        if(str[0]=='Q')
        {
            scanf("%d%d",&l,&r);
            printf("%lld\n",sum[r]-sum[l-1]+query(r)-query(l-1));
        }
        else
        {
            scanf("%d%d%d",&l,&r,&p);
            add(l,p);
            p=-p;
            add(r+1,p);
        }
    }
return 0; 
}

參考

發佈了40 篇原創文章 · 獲贊 51 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章