zoukankan      html  css  js  c++  java
  • HDU 4027 线段树 Can you answer these queries?

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4027

    道题最关键的一个地方就是区间更新!

    思路: 一开始看到这题,最先想到的就是结点更新, 但是,这样做是超时的.其实, 这里有一个地方有点难想到,当某个结点的值为1时,开多少次方都还是1,这样就浪费了很多时间. 所以, 加一个标记,如果某个区间里的值全为1, 就不继续往下更新.

    以下是AC代码:

    #include<iostream>
    #include<string>
    #include<cstring>
    #include<algorithm>
    #include<cstdio>
    #include<cmath>
    #include<cctype>
    #include<iomanip>
    
    #define MID  (f[rt].l+f[rt].r)>>1
    
    using namespace std;
    const int maxn=100000;
    
    struct node{
        __int64 sum;
        int l,r;
        bool k;
    }f[maxn<<2];
    
    void PushUp(int rt){
        f[rt].sum=f[rt<<1].sum+f[rt<<1|1].sum;
        f[rt].k = f[rt<<1].k&&f[rt<<1|1].k;///如果两个子结点都不用更新,那自己也不用更新了
    }
    
    void build(int L,int R,int rt){
        f[rt].l=L, f[rt].r=R, f[rt].k=false;
        if(L==R){
            scanf("%I64d",&f[rt].sum);
            if(f[rt].sum==1)f[rt].k=true;
            return ;
        }
        int mid=MID;
        build(L,mid,rt<<1);
        build(mid+1,R,rt<<1|1);
        PushUp(rt);
    }
    
    void update(int L,int R,int rt){
        if(f[rt].k)return;///不用更新了
        if(f[rt].l==f[rt].r){
            f[rt].sum = sqrt(f[rt].sum*1.0);
            if(f[rt].sum==1) f[rt].k=true;
            return;
        }
        int mid=MID;
        if(L<=mid) update(L,R,rt<<1);
        if(R> mid) update(L,R,rt<<1|1);
        PushUp(rt);
    }
    
    __int64 query(int L,int R,int rt){
        if(L<=f[rt].l&&R>=f[rt].r)
            return f[rt].sum;
        __int64 ret=0;
        int mid=MID;
        if(L<=mid) ret+=query(L,R,rt<<1);
        if(R> mid) ret+=query(L,R,rt<<1|1);
        return ret;
    }
    
    int main(){
        int n,cas=1;
        while(~scanf("%d",&n)){
            build(1,n,1);
            int m; scanf("%d",&m);
            printf("Case #%d:\n",cas++);
            while(m--){
                int c,x,y; scanf("%d%d%d",&c,&x,&y);
                if(x>y)swap(x,y);///这里一定要注意
                if(c)printf("%I64d\n",query(x,y,1));
                else update(x,y,1);
            }
            puts("");
        }
        return 0;
    }
    


  • 相关阅读:
    第五次作业
    第四次作业
    第三次作业
    第二次作业
    第5次作业
    4
    第三次
    2
    11
    第五次作业
  • 原文地址:https://www.cnblogs.com/javawebsoa/p/3045712.html
Copyright © 2011-2022 走看看