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

一个人养lyd,每盆lyd都有一个价值,lyd是排成一行。有三个操作:有时某盆lyd的价值会上升,有时某盆lyd的价值会下降。有时他想知道某段连续的lyd的价值之和是多少,你能快速地告诉她结果吗?


 

第一行一个整数T,表示有T组测试数据。
每组测试数据的第一行为一个正整数N (N<=50000),表示有N盆lyd。
接下来有N个正整数,第i个正整数a表示第i盆lyd的初始价值。
接下来每行有一条命令,命令有4种形式:
(1)Add i j, i和j为正整数,表示第i盆lyd价值增加j (j<=30)
(2)Sub i j, i和j为正整数,表示第i盆lyd价值减少j (j<=30)
(3)Query i j, i和j为正整数,i<=j,表示询问第i盆lyd到第j盆lyd的价值之和
(4)End,表示结束,这条命令在每组数据最后出现
每组数据的命令不超过40000条


 

 

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<cstring>
#include<stdio.h>
#include<algorithm>
#include<map>
#include<queue>
#include<set>
#include <sstream>
#include<vector>
#include<cmath>    
#include<stack>
#include<time.h>
#include<ctime>
using namespace std;
#define inf 1<<30
#define eps 1e-7
#define LD long double
#define LL long long
#define maxn 100000005
struct node
{
    int L, R, sum;
}tree[maxn];
int num[maxn] = {};
void update(int step)
{
    tree[step].sum = tree[step << 1].sum + tree[step << 1 | 1].sum;
}
void buildTree(int step,int L,int R)//先把树建了
{
    tree[step].L = L;
    tree[step].R = R;
    if (L == R)
    {
        tree[step].sum = num[L];
        return;
    }
    int mid = (L + R) >> 1;
    buildTree(step << 1, L, mid);//建左子树
    buildTree(step << 1 | 1, mid + 1, R);//建右子树
    update(step);
}
void change(int step, int L, int R, int val)//对树进行修改
{
    if (L <= tree[step].L && tree[step].R <= R)//当要修改的范围在当前点的范围之内时
    {
        tree[step].sum += val;//修改
        return;
    }
    int mid = (tree[step].L + tree[step].R) >> 1;
    if (R <= mid)//要修改的点在左子树时
        change(step * 2, L, R, val);
    else//要修改的点在右子树时
        change(step * 2 + 1, L, R, val);
    update(step);//对所有包含修改点的树进行修改
}
int query(int step, int L, int R)//求部分范围之和
{
    if (L <= tree[step].L && tree[step].R <= R)return tree[step].sum;//在当前点范围内
    if (L > tree[step].R || R < tree[step].L)return 0;//在当前点范围外
    return query(step * 2, L, R) + query(step * 2 + 1, L, R);//一部分在当前点内,一部分在当前点外
}
int main()
{
    int T, Case = 1;
    string s;
    scanf("%d", &T);
    while (T--)
    {
        int N, x, y, ans = 0;
        scanf("%d", &N);
        for (int i = 1; i <= N; i++)
        {
            scanf("%d", &num[i]);
        }
        buildTree(1, 1, N);
        printf("Case %d:\n", Case++);//格式
        while (cin >> s)
        {
            if (s == "End")
            {
                break;
            }
            else if (s == "Add")
            {
                scanf("%d%d", &x, &y);
                change(1, x, x, y);
            }
            else if (s == "Sub")
            {
                scanf("%d%d", &x, &y);
                change(1, x, x, -1 * y);
            }
            else if (s == "Query")
            {
                scanf("%d%d", &x, &y);
                ans=query(1,x, y);
                printf("%d\n", ans);
            }
        }
    }
}

 


 

posted @ 2020-07-21 00:17  夜灯长明  阅读(95)  评论(0编辑  收藏  举报