【HDU-4027】Can you answer these queries?

100 阅读1分钟
题意

首先给出一个数字n代表,然后又n个数据。

再给出一个数字k,代表n次查询,查询分为两种:

​ 0 x y:将 [x,y ]区间的每个数字开根号

​ 1 x y:=求[x,y ]区间和,并输出

 

 

样例
Sample Input
10
1 2 3 4 5 6 7 8 9 10
5
0 1 10
1 1 10
1 1 5
0 5 8
1 4 8
 

Sample Output
Case #1:
19
7
6

 



 

AC代码
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include<iostream>
using namespace std;

const int MAX = 100102;
typedef long long LL;
LL tree[MAX], a[MAX];
int n,m,t,x,y;

int lowbit(int x)
{
    return x&(-x);
}

void update(int x, LL val)
{
    for(int i=x; i<=n; i += lowbit(i))
        tree[i] += val;
}

LL getsum(int x)
{
    LL sum = 0;
    for(int i=x; i>0;i -= lowbit(i))
        sum += tree[i];
    return sum;
}

int main()
{
    //freopen("a.txt","r",stdin);

    int count = 1;
    while(~scanf("%d",&n))  //等价于while(scanf("%d",&n)!=EOF)
    {
        memset(tree, 0, sizeof(tree) );
        for(int i=1; i<=n; ++i)
        {
            scanf("%I64d", &a[i]);  
            update(i, a[i]);          //创建树状数组
        }
        scanf("%d",&m);
        printf("Case #%d:\n",count++);
        while(m--)
        {
            cin>>t>>x>>y;
            if(x>y)
                swap(x,y);    
            if(t==0)
            {
                if(getsum(y) - getsum(x-1) <= y - x + 1)      如果区间内的所有数都是1则不必更新
                    continue;
                else
                {
                    for(int j=x; j<=y; j++)
                    {
                        if(a[j] <= 1)   ///这里如果写成“if(a[j]==1)”   ,也能通过
                           continue;  
                        update(j, -a[j]);
                        a[j] = (LL)sqrt(a[j]); //进行开方,注意数据类型要转换一下
                        update(j,a[j]);  //更新树状数组
                    }
                }
            }
            else
            {
                LL ans = getsum(y) - getsum(x-1);
                printf("%I64d\n",ans);
            }
        }
        cout<<endl;
    }
    return 0;
}

 

题源:acm.hdu.edu.cn/showproblem…

参考:blog.csdn.net/yew1eb/arti…