HDU1146敌兵布阵-线段树入门模板题


稍微解释一下lazy变量的作用:
为了避免对无需查询的线段树节点进行更新(浪费了没有必要的时间),我们可以建立一个lazy变量,来暂时储存一个节点对之后节点的增量
(在询问到这个节点以后,当我们发现他并不是我们查询的确切空间,再使用lazy对他的子节点(子节点具有更精确的范围)进行更新)
#include
#define  ll long long
#define maxn 50500
using namespace std;
ll a[maxn];
struct tree{
    int l;
    int r;
    int val;
    int lazy;
}tree[4*maxn];
void pushdown(int root)
{
    tree[root*2].val+=tree[root].lazy*(tree[root*2].r-tree[root*2].l+1);
    tree[root*2+1].val+=tree[root].lazy*(tree[root*2+1].r-tree[root*2+1].l+1);
    tree[root*2].lazy+=tree[root].lazy;
    tree[root*2+1].lazy+=tree[root].lazy;
    tree[root].lazy=0;
}
void build(int root,int left,int right)
{
    int mid=(left+right)>>1;
    tree[root].l=left;
    tree[root].r=right;
    tree[root].val=0;
    tree[root].lazy=0;
    if(left==right)
    {
        tree[root].val=a[left];
        return;
    }
    build(root*2,left,mid);
    build(root*2+1,mid+1,right);
    tree[root].val=tree[root*2].val+tree[root*2+1].val;
}
int quiry(int root,int left,int right)
{
    int mid=(tree[root].l+tree[root].r)>>1;
    if(tree[root].l>=left&&tree[root].r<=right)
        return tree[root].val;
    if(tree[root].lazy)
        pushdown(root);
    if(right<=mid)
        return quiry(root*2,left,right);
    if(left>mid)
        return quiry(root*2+1,left,right);
    return quiry(root*2,left,mid)+quiry(root*2+1,mid+1,right);
}
void update(int root,int left,int right,int val)
{
    if(left<=tree[root].l&&right>=tree[root].r)
    {
        tree[root].val+=val*(right-left+1);
        tree[root].lazy+=val;
        return ;
    }
    pushdown(root);
    int mid=(tree[root].l+tree[root].r)>>1;
    if(right<=mid)
        update(root*2,left,right,val);
    else if(left>mid)
        update(root*2+1,left,right,val);
    else
    {
        update(root*2,left,mid,val);
        update(root*2+1,mid+1,right,val);
    }
    tree[root].val=tree[root*2].val+tree[root*2+1].val;
}
int main()
{
    int t;
    cin>>t;
    for(int i=1;i<=t;i++)
    {
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
            scanf("%lld",&a[i]);
        build(1,1,n);
        printf("Case %d:\n",i);
        while(1)
        {
            char s[15];
            scanf("%s",s);
            if(s[0]=='Q')
            {
                int a,b;
                scanf("%d%d",&a,&b);
                printf("%d\n",quiry(1,a,b));
            }
            else if(s[0]=='A')
            {
                int a,b;
                scanf("%d%d",&a,&b);
                update(1,a,a,b);

            }
            else if(s[0]=='S')
            {
                int a,b;
                scanf("%d%d",&a,&b);
                update(1,a,a,-b);
            }
            else
            {
                break;
            }
        }
    }
}

你可能感兴趣的:(HDU1146敌兵布阵-线段树入门模板题)