HDU4027:Can you answer these queries?(点更新,区间查,l和r比较巨坑!!)

来源:互联网 发布:中国食品出口美国数据 编辑:程序博客网 时间:2024/06/13 03:26

题意:

给n个数字, 操作0将l->r的数字都变为原来的sqrt,操作1询问l->r的区间和。

思路:

注意在1的时候我们就不需要再做根号了,因为sqrt1==1 因此可以快速维护出一个解答的区间!

最有意思的是 l可能大于r 真坑!


#include <stdio.h>#include <algorithm>#include <cstring>#include <iostream>#include <cmath>using namespace std;const int maxn= 10000005;struct node{    int left,right,vis;    long long num,sum;}tree[4*maxn];void Build(int i,int left,int right){    tree[i].left=left,tree[i].right=right;    tree[i].vis=0;    if(left==right)    {        scanf("%lld",&tree[i].num);        tree[i].sum=tree[i].num;        return ;    }    int mid=(tree[i].left+tree[i].right)>>1;    Build(i<<1,left,mid);    Build(i<<1|1,mid+1,right);    tree[i].sum=tree[i<<1].sum+tree[i<<1|1].sum;    return ;}long long ans=0;void query(int i,int left,int right){    if(tree[i].right==right&&tree[i].left==left)    {        ans+=tree[i].sum;        return ;    }    int mid=(tree[i].left+tree[i].right)>>1;    if(left>mid)    {        query(i<<1|1,left,right);    }    else if(right<=mid)    {        query(i<<1,left,right);    }    else    {        query(i<<1,left,mid);        query(i<<1|1,mid+1,right);    }    return ;}void update(int i,int left,int right){    if(tree[i].vis)        return ;    if(tree[i].right==tree[i].left)    {        tree[i].num=sqrt(tree[i].num);        tree[i].sum=tree[i].num;        if(1==tree[i].num)            tree[i].vis=1;        return ;    }    int mid=(tree[i].left+tree[i].right)>>1;    if(left>mid)    {        update(i<<1|1,left,right);    }    else if(right<=mid)    {        update(i<<1,left,right);    }    else    {        update(i<<1,left,mid);        update(i<<1|1,mid+1,right);    }    tree[i].vis=tree[i<<1].vis&&tree[i<<1|1].vis;    tree[i].sum=tree[i<<1].sum+tree[i<<1|1].sum;    return ;}int main(){    int n,q;int t=0;    while(~scanf("%lld",&n ))    {      printf("Case #%d:\n",++t);    Build(1,1,n);    scanf("%lld",&q );    while(q--)    {        long long  op,l,r;        scanf("%lld%lld%lld",&op,&l,&r);        if(l>r)            swap(l,r);        if(op==1)        {        ans=0;        query(1,l,r);        printf("%lld\n",ans );        }        else        {            update(1,l,r);        }    }        printf("\n");    }}


0 0