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;
    }
    勿忘初心
  • 相关阅读:
    核主成分分析方法(KPCA)怎么理解?
    通过主成分分析方法进行降维
    线性回归分析中的假设检验
    机器学习中的逻辑回归方法
    关联分析中寻找频繁项集的FP-growth方法
    机器学习中的模型选择和特征选择的基本方法
    计算学习理论中泛化误差的研究
    《幸福的陷阱》读书笔记
    人生规划的逆向思维
    为什么相敬如宾是对的?
  • 原文地址:https://www.cnblogs.com/YY56/p/4738471.html
Copyright © 2011-2022 走看看