• HDOJ 4027 Can you answer these queries?


    此题陷阱多多:数据类型(相应的输入输出)、区间端点可能反序、如果用C提交注意强制转换的格式(int(x)是不对的);

    思路:每次如果开根号的区间内含有未达到0或1的数就一直向下,找到这些数并直接更新一次,这样最多跟新4*N次,加上线段树的复杂度,为4*N*lgN,是最坏情况的复杂度,可能由于开根号耗时较多,总体比较耗时(700ms+),查询的复杂度为lgN。

    # include <stdio.h>
    # include <math.h>
    
    # define N 100005
    
    # define ls ((r)<<1)
    # define rs ((r)<<1|1)
    # define mid (((x)+(y))>>1)
    
    typedef long long int LL;
    
    LL n, m;
    char bott[N<<2];
    LL sum[N<<2];
    
    LL root(LL x)
    {
            return (LL)floor(sqrt(x));
    }
    
    void update(LL r)
    {
        sum[r] = sum[ls] + sum[rs];
        bott[r] = bott[ls] & bott[rs];
    }
    
    void build(LL r, LL x, LL y)
    {
        bott[r] = 0;
        if (x == y)
        {
            scanf("%I64d", &sum[r]);
            return ;
        }
        build(ls, x, mid);
        build(rs, mid+1, y);
        update(r);
    }
    
    void srt(LL r, LL x, LL y, LL s, LL t)
    {
        if (s<=x && y<=t)
        {
            if (bott[r]) return ;
            else if (x == y)
            {
                sum[r] = root(sum[r]);
                if (sum[r] < 2) bott[r] = 1;
                return ;
            }
        }
        if (s <= mid) srt(ls, x, mid, s, t);
        if (mid+1 <= t) srt(rs, mid+1, y, s, t);
        update(r);
    }
    
    void query(LL r, LL x, LL y, LL s, LL t, LL *ans)
    {
        if (s<=x && y<=t)
        {
            *ans += sum[r];
            return ;
        }
        if (s<=mid) query(ls, x, mid, s, t, ans);
        if (mid+1<=t) query(rs, mid+1, y, s, t, ans);
    }
    
    void solve(void)
    {
        LL i, op, s, t, tmp; LL ans;
        scanf("%I64d", &m);
        for (i = 1; i <= m; ++i)
        {
            scanf("%I64d%I64d%I64d", &op, &s, &t);
            //printf("%I64d %I64d %I64d\n", op, s, t);
            if (s > t) tmp = s, s = t, t = tmp;
            if (op == 0)    srt(1, 1, n, s, t);
            else
            {
                ans = 0;
                query(1, 1, n, s, t, &ans);
                printf("%I64d\n", ans);
            }
        }
    }
    
    int main()
    {
        LL icase = 0;
        while (~scanf("%I64d", &n))
        {
            printf("Case #%I64d:\n", ++icase);
            build(1, 1, n);
            solve();
            putchar('\n');
        }
    
        return 0;
    }
  • 相关阅读:
    POJ 2955
    POJ 1276 多重背包
    UVA 11584 划分回文字串
    Uva 11400 照明系统
    POJ 2677 Tour
    Uva 437 巴比伦塔 && UVA10003
    12563 Jin Ge Jin Qu hao
    最小公共祖先 (Tarjan) POJ1470
    DB2
    SQLserver数据库
  • 原文地址:https://www.cnblogs.com/JMDWQ/p/2654796.html
Copyright © 2020-2023  润新知