HDU 1166 树状数组和线段树

树状数组

#include<bits/stdc++.h>
using namespace std;
long long  data[50001],s[50001],T[50001];
long long  lowbit(long long t)
{
    return t&(-t);
}
long long  sum(long long  eend)
{
    long long  sum=0;
    while(eend>0)
    {
        sum+=T[eend];
        eend-=lowbit(eend);
    }
    return sum;
}
void pplus(long long  pos,long long  num,long long  ccount)
{
    while(pos<=ccount)
    {
        T[pos]+=num;
        pos+=lowbit(pos);
    }
}
int main()
{
    ios::sync_with_stdio(false);
    string str;
    int t,n,a,b;
    cin>>t;
    for(int i=1; i<=t; i++)
    {
        cin>>n;
        T[0]=s[0]=data[0]=0;
        for(int j=1; j<=n; j++)
        {
            cin>>data[j];
            s[j]=s[j-1]+data[j];
            T[j]=s[j]-s[j-lowbit(j)];
        }
        cout<<"Case "<<i<<":"<<endl;
        while(cin>>str&&str!="End")
        {
            cin>>a>>b;
            if(str=="Query")
                cout<<sum(b)-sum(a)+data[a]<<endl;
            else if(str=="Add")
                pplus(a,b,n),data[a]+=b;
            else pplus(a,-b,n),data[a]-=b;
        }
    }
}

线段树

#include<bits/stdc++.h>
using namespace std;
const int N= 50000;
struct node
{
    int l,r;
    long long sum;
};
node tree[N*3];
void buildtree(int l,int r,int pos)
{
    tree[pos].l=l;
    tree[pos].r=r;
    if(l==r)
    {
        cin>>tree[pos].sum;
        return ;
    }
    int mid=(l+r)>>1;
    buildtree(l,mid,pos*2);
    buildtree(mid+1,r,pos*2+1);
    tree[pos].sum=tree[pos*2].sum+tree[pos*2+1].sum;
}
long long query(int l,int r,int pos)
{
    if(l==tree[pos].l&&r==tree[pos].r)
        return tree[pos].sum;
    else if(r<=(tree[pos].l+tree[pos].r)/2)
        return query(l,r,pos<<1);
    else if(l>=(tree[pos].l+tree[pos].r)/2+1)
        return query(l,r,(pos<<1)+1);
    else
        return query(l,tree[pos*2].r,pos*2)+query(tree[pos*2+1].l,r,pos*2+1);
}
void update(int pos,int k,int add)
{
    if(k>=tree[pos].l&&k<=tree[pos].r)
    {
        tree[pos].sum+=add;
        if(tree[pos].l==tree[pos].r)
            return ;
        update(pos*2,k,add);
        update(pos*2+1,k,add);
    }
    return ;
}
int main()
{
    ios::sync_with_stdio(false);
    string str;
    int t,n,a,b;
    cin>>t;
    for(int i=1; i<=t; i++)
    {
        cin>>n;
        cout<<"Case "<<i<<":"<<endl;
        buildtree(1,n,1);
        while(cin>>str&&str!="End")
        {
            cin>>a>>b;
            if(str=="Query")
                cout<<query(a,b,1)<<endl;
            else if(str=="Add")
                update(1,a,b);
            else update(1,a,-b);
        }
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值