zoukankan      html  css  js  c++  java
  • 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;
    }
    
  • 相关阅读:
    BZOJ5311,CF321E 贞鱼
    POJ3208 Apocalypse Someday
    POJ1037 A decorative fence
    POJ1737 Connected Graph
    CF559C Gerald and Giant Chess
    NOI2009 诗人小G
    Problem 2726. -- [SDOI2012]任务安排
    POJ1821 Fence
    HDU5542 The Battle of Chibi
    POJ2376 Cleaning Shifts
  • 原文地址:https://www.cnblogs.com/qie-wei/p/10160124.html
Copyright © 2011-2022 走看看