Can you answer these queries? HDU 4027

http://acm.hdu.edu.cn/showproblem.php?pid=4027

题意:给出一个为 n 的区间, 1 - n 分别有相对应的值(大小为2^63)。 有两种操作, 一是改变从 i - j 区间的值, 改变方法是把 i - j 区间每个数都开方, 而是求从 i - j 区间这些数 的总和。

分析:因为这个操作是把一个数变成平方根,所以显得略棘手,不过如果仔细演算的话会发现一个2^64数的平方根开8次也就变成了 1,所以也更新不了多少次,所以可以每次更新到底。
 
注意:给的X Y大小未知,会出现X > Y的情况
 
#include <iostream>
#include <string.h>
#include <stdio.h>
#include <algorithm>
#include <math.h>
#include <vector>
using namespace std;
typedef long long LL;
const int oo = 0xfffffff;
const int maxn = 110007;
#define lson rt<<1
#define rson rt<<1|1
__int64 A[maxn];
/*
    注意到2的63次方 开根号8次就到1了,所以判断rt左右两边端点值是否为1
*/

struct node
{
    int l, r, flag;
    __int64 sum;
} tree[maxn<<2];

void build(int l, int r, int rt)
{
    tree[rt].l = l;
    tree[rt].r = r;
    tree[rt].flag = 0;

    if(l==r)
    {
        tree[rt].sum = A[l];

        if(tree[rt].sum==1)
            tree[rt].flag=1;

        return ;
    }

    int mid=(l+r)/2;
    build(l, mid , lson);
    build(mid+1, r, rson);

    tree[rt].sum = tree[lson].sum + tree[rson].sum;

    if(tree[lson].flag == 1 && tree[rson].flag == 1)
        tree[rt].flag = 1;

}

void update(int l, int r, int rt)
{
    if(tree[rt].flag == 1)
        return ;

    if(tree[rt].l == tree[rt].r)
    {
        tree[rt].sum = (__int64)sqrt(tree[rt].sum);

       if(tree[rt].sum == 1)
        tree[rt].flag = 1;

        return ;
    }

    int mid = (tree[rt].l + tree[rt].r)/2;

    if(r<=mid) update(l, r, lson);
    else if(l>mid)  update(l, r, rson);
    else
    {
        update(l, mid, lson);
        update(mid+1, r, rson);
    }

        //从头到尾得再重新更新值
    tree[rt].sum = tree[lson].sum + tree[rson].sum;

    if(tree[lson].flag == 1 && tree[rson].flag ==1)
        tree[rt].flag = 1;
}

__int64 query(int l, int r, int rt)
{

    if(tree[rt].flag == 1) return r-l+1;
    if(tree[rt].l == l && tree[rt].r == r)
        return tree[rt].sum;

    int mid = (tree[rt].l + tree[rt].r)/2;

    if(r<=mid) return query(l, r ,lson);
    else if(l>mid) return query(l, r, rson);
    else
    {
       __int64 lsum, rsum;
        lsum = query(l, mid, lson);
        rsum = query(mid+1, r, rson);
        return lsum+rsum;
    }

}
int main()
{
    int n, q, i, cnt=1;

    while(scanf("%d",&n) != EOF)
    {

        for(i=1; i<=n; i++)
            scanf("%I64d",&A[i]);

        build(1, n, 1);

        scanf("%d",&q);
        printf("Case #%d:
",cnt++);

        while(q--)
        {
            int a, b, c;

            scanf("%d %d %d", &a, &b, &c);

             int t=c;
              if(b>c)
              {
                  t=b;
                  b=c;
                  c=t;
              }

            if(a)
            {
                printf("%I64d
",query(b, c, 1));
                continue;
            }

            update(b, c, 1);
        }
        printf("
");
    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/daydayupacm/p/5683533.html