您的位置:首页 > 产品设计 > UI/UE

hdu 4027 Can you answer these queries?

2013-08-17 23:12 363 查看
题目大意:

给出N个数

0 操作 把 l ----- r之间的数全部开平方

1 操作 输出 l -----r 之间的和

开始是想找那个公式 怎么转化的 。

因为 sum的数据范围是在 2^63 一下 所以最多开7次方就可以得到 1了

而且他所谓的开方 是开放了以后向下取整。

用一个cov标记这个区间是否已经全部为1了

#include <iostream>
#include <cstdio>
#include <cmath>
#define maxn 100005
#define lson num<<1,s,mid
#define rson num<<1|1,mid+1,e
typedef __int64 LL;
using namespace std;

LL tree[maxn<<2];
int cov[maxn<<2];

LL sq(LL x)
{
    return (LL)sqrt(1.0*x);
}

void pushup(int num)
{
    tree[num]=tree[num<<1]+tree[num<<1|1];
    cov[num]=(cov[num<<1]&cov[num<<1|1]);
}

void build(int num,int s,int e)
{
    cov[num]=0;
    if(s==e)
    {
        scanf("%I64d",&tree[num]);
        if(tree[num]==1)cov[num]=1;
        return;
    }
    int mid=(s+e)>>1;
    build(lson);
    build(rson);
    
    pushup(num);
}
LL query(int num,int s,int e,int l,int r)
{
    int mid=(s+e)>>1;

    if(l<=s && r>=e)
    {
        return tree[num];
    }
    if(l>mid)return query(rson,l,r);
    else if(r<=mid)return query(lson,l,r);
    else return query(lson,l,mid)+query(rson,mid+1,r);
}
void update(int num,int s,int e,int l,int r)
{
    int mid=(s+e)>>1;

    if(cov[num])return;

    if(s==e)
    {
        tree[num]=sq(tree[num]);
        if(tree[num]==1)cov[num]=1;

        return;
    }
    if(l<=mid)update(lson,l,r);
    if(r>mid)update(rson,l,r);
    
    pushup(num);
}
int main()
{
    int CASE=1;
    bool first=false;
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        printf("Case #%d:\n",CASE++);
        
        build(1,1,n);
        int m;
        scanf("%d",&m);
        while(m--)
        {
            int op,l,r;
            scanf("%d%d%d",&op,&l,&r);

            if(l>r)swap(l,r);

            if(!op)
            {
                update(1,1,n,l,r);
            }
            else
            {
                printf("%I64d\n",query(1,1,n,l,r));
            }
        }
        puts("");
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: