树状数组种类合集

单点更新,区间查询
hdu1166

#include<bits/stdc++.h>
using namespace std;

const int maxn=50005;
int num[maxn],tree[maxn];
int n;

int lowbit(int x)
{
    return x&(-x);
}

void updata(int pos,int k)
{
    for(int i=pos;i<=n;i+=lowbit(i))
    {
        tree[i]+=k;
    }
}

int query(int pos)
{
    int ans=0;
    while(pos>0)
    {
        ans+=tree[pos];
        pos-=lowbit(pos);
    }
    return ans;
}

void init()
{
    memset(tree,0,sizeof(tree));
}

int main()
{
    int t,ca=0;
    scanf("%d",&t);
    while(t--)
    {
        init();
        printf("Case %d:\n",++ca);
        scanf("%d",&n);
        for(int i=1;i<=n;i++)scanf("%d",&num[i]),updata(i,num[i]);
        char o[10];
        int x,y;
        while(~scanf("%s",o))
        {
            if(o[0]=='E')break;
            scanf("%d%d",&x,&y);
            if(o[0]=='Q')
            {
                printf("%d\n",query(y)-query(x-1));
            }
            else if(o[0]=='A')
            {
                updata(x,y);
            }
            else if(o[0]=='S')
            {
                updata(x,-y);
            }
        }
    }
}

询问区间极大值
hdu1754

#include<bits/stdc++.h>
using namespace std;

const int maxn=200005;
int num[maxn],tree[maxn];
int n,m;

int lowbit(int x)
{
    return x&(-x);
}

void updata(int pos,int k)
{
    num[pos]=k;
    for(int i=pos;i<=n;i+=lowbit(i))
    {
        tree[i]=num[i];
        for(int j=1;j<lowbit(i);j<<=1)
            tree[i]=max(tree[i],tree[i-j]);
    }
}

int query(int l,int r)
{
    int ans=num[r];
    while(true)
    {
        ans=max(ans,num[r]);
        if(l==r)break;
        for(--r;r-l>=lowbit(r);r-=lowbit(r))
            ans=max(ans,tree[r]);
    }
    return ans;
}

void init()
{
    memset(tree,0,sizeof(tree));
}

int main()
{
    while(~scanf("%d%d",&n,&m))
    {
        init();
        for(int i=1;i<=n;i++)scanf("%d",&num[i]),updata(i,num[i]);
        char o[2];
        int x,y;
        for(int i=1;i<=m;i++)
        {
            scanf("%s%d%d",o,&x,&y);
            if(o[0]=='Q')
            {
                printf("%d\n",query(x,y));
            }
            else if(o[0]=='U')
            {
                updata(x,y);
            }
        }
    }
}

区间更新,区间询问//差分数组
poj3468

#include<iostream>
#include<stdio.h>
using namespace std;
typedef long long ll;
const ll maxn=100005;
ll num[maxn],tree1[maxn],tree2[maxn];
ll n,q;

ll lowbit(ll x)
{
    return x&(-x);
}

void updata(ll *p,ll pos,ll k)
{
    while(pos<=n)
    {
        p[pos]+=k;
        pos+=lowbit(pos);
    }
}

ll query(ll *p,ll pos)
{
    ll ans=0;
    while(pos>0)
    {
        ans+=p[pos];
        pos-=lowbit(pos);
    }
    return ans;
}

int main()
{
    scanf("%lld%lld",&n,&q);
    for(ll i=1;i<=n;i++)scanf("%lld",&num[i]),updata(tree1,i,num[i]-num[i-1]),updata(tree2,i,(i-1)*(num[i]-num[i-1]));
    char o[2];
    ll x,y,z;
    for(ll i=1;i<=q;i++)
    {
        scanf("%s",o);
        if(o[0]=='Q')
        {
            scanf("%lld%lld",&x,&y);
            ll tmp1=(x-1)*query(tree1,x-1)-query(tree2,x-1);
            ll tmp2=y*query(tree1,y)-query(tree2,y);
            printf("%lld\n",tmp2-tmp1);
        }
        else
        {
            scanf("%lld%lld%lld",&x,&y,&z);
            updata(tree1,x,z);
            updata(tree1,y+1,-z);
            updata(tree2,x,(x-1)*z);
            updata(tree2,y+1,y*(-z));
        }
    }
}

猜你喜欢

转载自blog.csdn.net/qq_40942372/article/details/82154606