• hdu 4027 Can you answer these queries?[线段树]


    题目

    题意:

    输入一个 :n  。(1<=n<<100000)

    输入n个数    (num<2^63)

    输入一个m :代表m个操作    (1<=m<<100000;)

    接下来m行,每行三个数a,b,c,如果a==0,执行操作1;如果a==1,执行操作2.   

    操作1:对[b,c]区间上的每一个数进行开平方操作

    操作2:对[b,c]区间求和,输出。

    一直超时,这道题的关键在于: 2^63−1也就最多开8次平方根,,,而且开到1时再开平方根还是1.

    所以再开到区间所有数都为1时就不再对这个区间更新,也就是当sum[rt]==r-l+1 时就返回上一层,这样就减小了更新时的操作

    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #define lson l,mid,rt<<1
    #define rson mid+1,r,rt<<1|1
    
    using namespace std;
    typedef long long LL;
    const int maxn = 1e5+10;
    
    LL sum[maxn*4];
    int n,m;
    
    int Max(int a,int b)
    {
        if(a>b) return a;
        else return b;
    }
    
    int Min(int a,int b)
    {
        if(a<b) return a;
        else return b;
    }
    void pushup(int rt)
    {
        sum[rt]=sum[rt<<1]+sum[rt<<1|1];
        return ;
    }
    
    void build(int l,int r,int rt)
    {
        sum[rt]=0;
        if(l==r) {
           scanf("%lld",&sum[rt]);
            return ;
        }
        int mid = (l+r)>>1;
        build(lson);
        build(rson);
        pushup(rt);
    }
    void update(int x,int y,int l,int r,int rt)
    {
        if(l==r){
            sum[rt]=sqrt(1.0*sum[rt]);
            return;
        }
        if(x<=l&&r<=y&&sum[rt]==r-l+1){
            return;
        }
        int mid = (l+r)>>1;
        if(x<=mid) update(x,y,lson);
        if(mid < y) update(x,y,rson);
        pushup(rt);
    }
    LL query(int x,int y,int l,int r,int rt)
    {
        if(x<=l&&r<=y) return sum[rt];
        int mid = (l+r)>>1;
        LL ans = 0;
        if(x<=mid) ans+=query(x,y,lson);
        if(mid<y) ans+=query(x,y,rson);
        return ans;
    }
    int main()
    {
        int Case = 1;
        int a,b,c,x,y;
        while(~scanf("%d",&n))
        {
            printf("Case #%d:
    ",Case++);
            build(1,n,1);
    
            scanf("%d",&m);
            for(int i=0;i<m;i++)
            {
               scanf("%d%d%d",&a,&b,&c);
                x=Min(b,c),y=Max(b,c);
                if(a==0){//update
                    update(x,y,1,n,1);
                }else{//query
                    LL res = query(x,y,1,n,1);
                  printf("%lld
    ",res);
                }
            }
            printf("
    ");
        }
    
        return 0;
    }
    
  • 相关阅读:
    苏菲玛索的早年写真真的迷人
    VC编程技巧:IE控件的高级用法
    玫举窗口句柄,然后用窗口句柄去取得进程ID,比较得到的进程ID是不是你的进程ID....
    一个封装的XMLHttp Object Pool and XMLHttp chunnel Pool,挺不错
    VSTS For Testers读书笔记(3)
    VSTS For Testers读书笔记(8)
    美丽的厦门
    VSTS For Testers读书笔记(10)
    VSTS For Testers读书笔记(7)
    VSTS For Testers读书笔记(12)
  • 原文地址:https://www.cnblogs.com/qie-wei/p/10160124.html
Copyright © 2020-2023  润新知