hdu 4027 Can you answer these queries?

来源:互联网 发布:js 星星特效 编辑:程序博客网 时间:2024/05/16 19:44

题目大意:

给出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,etypedef __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;}


原创粉丝点击