zoukankan      html  css  js  c++  java
  • 杭电1166--敌兵布阵(线段树 | 树状数组)

    给一些数, 有几个操作,求区间内数的和,修改区间内某个位置的值,---- > 区间求(修改)和。
    线段树:
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #define max(a, b) a>b?a:b
    const int MAXN = 50050;
    using namespace std;
    struct Node
    {
        int left, right, sum;
    } tree[MAXN*3];
    int n, num[MAXN];
    void Build(int root, int left, int right)
    {
        tree[root].left = left;
        tree[root].right = right;
        if(left == right)
        {
            tree[root].sum = num[left];
            return;        
        }
        int mid = (left+right)>>1;
        Build(root<<1, left, mid);
        Build(root<<1|1, mid+1, right);  //
        tree[root].sum = tree[root<<1].sum + tree[root<<1|1].sum;
    }
    void Update(int root, int pos, int val)
    {
        if(tree[root].left == tree[root].right)
        {
            tree[root].sum += val; return; 
        } 
        int mid = (tree[root].left + tree[root].right) >> 1;
        if(pos <= mid)
            Update(root<<1, pos, val);
        else
            Update(root<<1|1, pos, val);
        tree[root].sum = tree[root<<1].sum + tree[root<<1|1].sum;
    } 
    
    
    int Query(int root, int left, int right)
    {
        if(left == tree[root].left && right == tree[root].right)
            return tree[root].sum;
        int mid = (tree[root].left + tree[root].right) >> 1;
        if(right <= mid)
            return     Query(root<<1, left, right);
        else if(left > mid)
            return Query(root<<1|1, left, right);
        else
            return Query(root<<1, left, mid) + Query(root<<1|1, mid+1, right); 
        
    }
    int main()
    {
        int t, temp = 1;
        scanf("%d", &t);
        while(t--)
        {
            scanf("%d", &n);
            for(int i = 1; i <= n; i++)    
                scanf("%d", &num[i]);
            Build(1, 1, n);
            printf("Case %d:
    ", temp++);
            char str[20]; int a, b;
            while(~scanf("%s", str))
            {
                if(str[0] == 'E')
                    break;
                scanf("%d %d", &a, &b);
                if(str[0] == 'Q')
                    printf("%d
    ", Query(1, a, b));
                if(str[0] == 'S')
                    Update(1, a, -b);
                if(str[0] == 'A')
                    Update(1, a, b);
            }
        }
        return 0;
    }

    树状数组:


    函数Odd()求的是: 为pos在二进制下末尾0的个数;

    http://blog.csdn.net/cambridgeacm/article/details/7771782#
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    using namespace std;
    int n, a[50005];
    int Odd(int src)
    {
        return src & (src^(src-1));
    }
    void Update(int pos, int val)
    {
        while(pos <= n)
        {
            a[pos] += val;
            pos += Odd(pos);
        }
    }
    int Getsum(int pos)
    {
        int sum = 0;
        while(pos > 0)
        {
            sum += a[pos];
            pos -= Odd(pos);    
        }
        return sum;
    }
    int main()
    {
        int t;
        scanf("%d", &t);
        for(int Q = 1; Q <= t; Q++)
        {
            memset(a, 0, sizeof(a));
            scanf("%d", &n);
            for(int i = 1; i <= n; i++)
            {
                int num;
                scanf("%d", &num);
                Update(i, num);
            }
            printf("Case %d:
    ", Q);
            char str[10];
            while(scanf("%s", str), str[0] != 'E')
            {
                int a, b;
                scanf("%d %d", &a, &b);
                if(str[0] == 'A')
                    Update(a, b);
                else if(str[0] == 'S')
                    Update(a, -b);
                else //if(str[0] == 'Q');
                    printf("%d
    ", Getsum(b) - Getsum(a-1));
            }
        }
        return 0;    
    }

     New code:

    #include <cstdio>
    #include <cstring>
    #define N 50001
    int n, num[N];
    struct Node{
        int sum, left, right;
    }tree[N*3];
    int Build(int root, int left, int right){
        tree[root].left = left;
        tree[root].right = right;
        if(left == right)
            return tree[root].sum = num[left];
        int mid = (left+right) / 2;
        Build(root<<1, left, mid);
        Build(root<<1|1, mid+1, right);
        tree[root].sum = tree[root<<1].sum + tree[root<<1|1].sum;  
    }
    int Update(int root, int pos, int val){
        if(tree[root].left == tree[root].right)
            return tree[root].sum += val; 
        int mid = (tree[root].left+tree[root].right) / 2;
        if(pos  <= mid)
            Update(root<<1, pos, val);
        else
            Update(root<<1|1, pos, val);
        tree[root].sum = tree[root<<1].sum + tree[root<<1|1].sum; 
    } 
    int Query(int root, int left, int right){
        if(left == tree[root].left && right == tree[root].right)
            return tree[root].sum;
        int mid = (tree[root].left + tree[root].right) / 2;
        if(right <= mid)
            return Query(root<<1, left, right);
        else if(left > mid)
            return Query(root<<1|1, left, right);
        else
            return Query(root<<1, left, mid) + Query(root<<1|1, mid+1, right);
    }
    int main(){
        int t, tem = 1;
        scanf("%d", &t);
        while(t--){
            scanf("%d", &n);
            for(int i = 1; i <= n; i++)
                scanf("%d", &num[i]);
            Build(1, 1, n);
            printf("Case %d:
    ", tem++); char str[10];
            while(scanf("%s", str) != EOF){
                if(str[0] == 'E')
                    break; 
                int a, b;
                scanf("%d%d", &a, &b);
                if(str[0] == 'Q')
                    printf("%d
    ", Query(1, a, b));
                if(str[0] == 'A')
                    Update(1, a, b);
                if(str[0] == 'S')    
                    Update(1, a, -b);
            }
        }
        return 0;
    }
  • 相关阅读:
    歌词:青春
    转载:只输了五元钱
    极静之渊

    低学翁
    心灵死化,何时巨变?
    无题

    意念
    爱之切
  • 原文地址:https://www.cnblogs.com/soTired/p/4754470.html
Copyright © 2011-2022 走看看