HDU-1166 敌兵布阵 (线段树模板题)

题目:
https://cn.vjudge.net/problem/HDU-1166
代码:

/**
    线段树模板题
    预备小知识:
        1.a<>n;//相当于a/2^n,a>>2==a/2
**/
#include
#include
#include
#define N 50005
int num[N];
struct Node
{
    int left; //起点
    int right; //终点
    int data; //值
} nodes[N*4];
void Build(int left,int right,int root)
{//建树
    nodes[root].left=left;
    nodes[root].right=right;
    if(nodes[root].left==nodes[root].right)
    {//找到叶子节点
        nodes[root].data=num[left];
        return;
    }
    int mid=(left+right)/2;//开始二分
    Build(left,mid,root<<1);//建左子树
    Build(mid+1,right,root<<1|1);//建左子树
    nodes[root].data=nodes[root<<1].data+nodes[root<<1|1].data;//更新当前节点的值
}
int Find(int left,int right,int root)
{//查询函数
    if(nodes[root].left==left&&nodes[root].right==right)
        return nodes[root].data;//找到叶子节点,并返回其值
    int mid=(nodes[root].left+nodes[root].right)/2;//开始操作
    if(left>mid)//在右子树
        return Find(left,right,root<<1|1);
    else if(right<=mid)//在左子树
        return Find(left,right,root<<1);
    return Find(left,mid,root<<1)+Find(mid+1,right,root<<1|1);//在中间
}
void Update(int pos,int value,int root)
{//单点更新函数
    if(nodes[root].left==pos&&nodes[root].right==pos)
    {//找到叶子节点,并复制
        nodes[root].data=value;
        return;
    }
    int mid=(nodes[root].left+nodes[root].right)/2;//开始二分
    if(pos<=mid)//在左子树
        Update(pos,value,root<<1);
    else//在右子树
        Update(pos,value,root<<1|1);
    nodes[root].data=nodes[root<<1].data+nodes[root<<1|1].data;//更新当前节点的值
}

int main()
{
    int k,t,a,b;
    int i,n,m;
    char str[10];
    scanf("%d",&t);
    for(k=1; k<=t; k++)
    {
        scanf("%d",&n);
        for(i=1; i<=n; i++)
            scanf("%d",&num[i]);
        Build(1,n,1);
        printf("Case %d:\n",k);
        while(scanf("%s",str),strcmp(str,"End"))
        {
            scanf("%d%d",&a,&b);
            if(strcmp(str,"Query")==0)
                printf("%d\n",Find(a,b,1));
            else if(strcmp(str,"Add")==0)
            {
                num[a]+=b;
                m=num[a];
                Update(a,m,1);
            }
            else if(strcmp(str,"Sub")==0)
            {
                num[a]-=b;
                m=num[a];
                Update(a,m,1);
            }
        }
    }
    return 0;
}

你可能感兴趣的:(刷题)