zoukankan      html  css  js  c++  java
  • (线段树 点更新 区间求和)lightoj1112

    链接:

    http://acm.hust.edu.cn/vjudge/contest/view.action?cid=88230#problem/D (密码0817)

    Description

    Robin Hood likes to loot rich people since he helps the poor people with this money. Instead of keeping all the money together he does another trick. He keeps n sacks where he keeps this money. The sacks are numbered from 0 to n-1.

    Now each time he can he can do one of the three tasks.

    1)                  Give all the money of the ith sack to the poor, leaving the sack empty.

    2)                  Add new amount (given in input) in the ith sack.

    3)                  Find the total amount of money from ith sack to jth sack.

    Since he is not a programmer, he seeks your help.

    Input

    Input starts with an integer T (≤ 5), denoting the number of test cases.

    Each case contains two integers n (1 ≤ n ≤ 105) and q (1 ≤ q ≤ 50000). The next line contains n space separated integers in the range [0, 1000]. The ith integer denotes the initial amount of money in the ith sack (0 ≤ i < n).

    Each of the next q lines contains a task in one of the following form:

    1 i        Give all the money of the ith(0 ≤ i < n) sack to the poor.

    2 i v     Add money v (1 ≤ v ≤ 1000) to the ith(0 ≤ i < n) sack.

    3 i j      Find the total amount of money from ith sack to jth sack (0 ≤ i ≤ j < n).

    Output

    For each test case, print the case number first. If the query type is 1, then print the amount of money given to the poor. If the query type is 3, print the total amount from ith to jth sack.

    Sample Input

    1

    5 6

    3 2 1 4 5

    1 4

    2 3 4

    3 0 3

    1 2

    3 0 4

    1 1

    Sample Output

    Case 1:

    5

    14

    1

    13

    2

    代码:

    
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    
    
    #define Lson (r<<1)
    #define Rson (r<<1|1)
    #define Mid e[r].mid()
    
    const int N = 100005;
    
    struct node
    {
        int L, R, sum;
        int mid()
        {
            return (L+R)/2;
        }
    } e[N<<2];
    
    int a[N], sum;
    
    void BuildTree(int r, int L, int R)
    {
        e[r].L = L , e[r].R = R;
    
        if(L==R)
        {
            e[r].sum = a[L];
            return ;
        }
    
        BuildTree(Lson, L, Mid);
        BuildTree(Rson, Mid+1, R);
    
        e[r].sum = e[Lson].sum + e[Rson].sum;
    }
    
    void Oper(int r, int i, int w)
    {
        if(e[r].L == e[r].R)
        {
            e[r].sum = w;
            return ;
        }
        if(i<=Mid)
        Oper(Lson, i, w);
        else
        Oper(Rson, i, w);
    
        e[r].sum = e[Lson].sum + e[Rson].sum;
    }
    
    int Query(int r, int L, int R)
    {
        if(e[r].L==L && e[r].R==R)
          return e[r].sum;
    
        if(R<=Mid)
            return Query(Lson, L, R);
        else if(L>Mid)
            return Query(Rson, L, R);
        else
        {
            int LL = Query(Lson, L, Mid);
            int RR = Query(Rson, Mid+1, R);
    
            return LL + RR;
        }
    
    }
    
    
    int main()
    {
        int t, n, m, iCase=1;
        scanf("%d", &t);
    
        while(t--)
        {
          int i, L, R, w, x;
    
          scanf("%d%d", &n, &m);
    
          for(i=1; i<=n; i++)
            scanf("%d", &a[i]);
    
          BuildTree(1, 1, n);
    
          printf("Case %d:
    ", iCase++);
    
          while(m--)
          {
              scanf("%d", &x);
              if(x==3)
              {
                  scanf("%d%d", &L, &R);
                  sum = 0;
                  L++, R++;
                  printf("%d
    ", Query(1, L, R));
              }
              else
              {
                  scanf("%d", &i);
                  i++;
    
                  if(x==1)
                  {
                      printf("%d
    ", a[i]);
                      a[i] = 0;
                  }
                  else
                  {
                      scanf("%d", &w);
                      a[i] += w;
                  }
                  Oper(1, i, a[i]); ///由于都是点的操作,可以直接操做后在去操作树,感觉和直接操作树是一样的,不过对于///这题来说,这种似乎更好些, 因为有加和清零的,对点的操作是不一样的, 然而区间查询就很简单了,不说了
              }
          }
    
        }
        return 0;
    }
    勿忘初心
  • 相关阅读:
    2-1Java简介
    02-安装JDK
    任务34:Cookie-based认证实现
    任务31:课时介绍 & 任务32:Cookie-based认证介绍 &任务33:34课 :AccountController复制过来没有移除[Authorize]标签
    任务30:RoutingMiddleware介绍以及MVC引入
    任务29:自己动手构建RequestDelegate管道
    任务28:RequestDelegate管道实现思路
    任务27:Middleware管道介绍
    任务26:dotnet watch run 和attach到进程调试
    任务25:IHostEnvironment和 IApplicationLifetime介绍
  • 原文地址:https://www.cnblogs.com/YY56/p/4738471.html
Copyright © 2011-2022 走看看