zoukankan      html  css  js  c++  java
  • 线段树

    • 题目要求维护区间开方和,但由于

      [tree[root] eq sqrt(tree[leftroot] +tree[rightroot]) ]

      因此每一个更新操作都需要深入到叶子结点

    • 由于这么做复杂度太高,甚至弱于普通数组,因此考虑优化

      [tree[root] = right - left+1 表明[left,right]区间全为1,再开方更新仍为1 ]

      因此再update操作时判断一下,进行剪枝

    • 本题坑点是输入数据不保证(l < r),需要特判替换,否则TLE

    • 注意开long long

    #include <cstdio>
    #include <cmath>
    #include <cstdlib>
    using namespace std;
    #define N 100000+5
    typedef long long ll;
    
    ll arr[N];
    ll tree[N<<2];
    
    void build_tree(int left,int right,int root){
        if(left == right){
            tree[root] = arr[left];
        }else{
            int mid = (left+right)>>1;
            int left_root = root<<1;
            int right_root = root<<1|1;
            build_tree(left,mid,left_root);
            build_tree(mid+1,right,right_root);
            tree[root] = tree[left_root]+tree[right_root];
        }
    }
    
    void update(int left,int right,int root,int update_left,int update_right){
        if(update_left > right || update_right < left || tree[root] == right-left+1){
            return;
        }else{
            if(left == right){
                tree[root] = (int)sqrt(tree[root]);
            }else{
                int mid = (left+right)>>1;
                int left_root = root<<1;
                int right_root = root<<1|1;
                update(left,mid,left_root,update_left,update_right);
                update(mid+1,right,right_root,update_left,update_right);
                tree[root] = tree[left_root] + tree[right_root];
            }
        }
    }
    
    ll query(int left,int right,int root,int query_left,int query_right){
        if(query_left <= left && query_right >= right){
            return tree[root];
        }else{
            int mid = (left+right)>>1;
            int left_root = root<<1;
            int right_root = root<<1|1;
            ll ans = 0;
            if(query_left <= mid){
                ans += query(left,mid,left_root,query_left,query_right);
            }
            if(query_right > mid){
                ans += query(mid+1,right,right_root,query_left,query_right);
            }
            return ans;
        }
    }
    
    int main(){
        int n;
        int g = 1;
        while(scanf("%d",&n) != EOF){
            printf("Case #%d:
    ",g++);
            for(int i = 1; i <= n; i++){
                scanf("%lld",&arr[i]);
            }
            build_tree(1,n,1);
            int q;
            int a,b,c;
            scanf("%d",&q);
            while(q--){
                scanf("%d%d%d",&a,&b,&c);
                if(b > c){
                    int temp = c;
                    c = b;
                    b = temp;
                }
                if(a == 0){
                    update(1,n,1,b,c);
                }else{
                    printf("%lld
    ",query(1,n,1,b,c));
                }
            }
            putchar('
    ');
        }
        system("pause");
        return 0;
    }
    
    
    ---- suffer now and live the rest of your life as a champion ----
  • 相关阅读:
    机器人学——1.6-双向量表示法
    机器人学——1.5-奇异点及万向节锁
    机器人学——1.4-三角度表示法
    机器人学——1.3-正交旋转矩阵
    MySQL数据库操作
    ArrayList和LinkedList的区别
    redis 常用命令
    idea快捷键
    Spring
    JDBC
  • 原文地址:https://www.cnblogs.com/popodynasty/p/13895037.html
Copyright © 2011-2022 走看看