H - Can you answer these queries? - (区间查询更新)

有一列数,(都是2^63范围内的并且都大于0的整数),现在呢有一些操作, 操作 0 可以把区间LR内的所有数都变成它的平方根数(是取整后的),操作 1 可以就是求区间LR内的和了。
分析:因为这个操作是把一个数变成平方根,所以显得略棘手,不过如果仔细演算的话会发现一个2^64数的平方根开8次也就变成了 1,所以也更新不了多少次,所以可以每次更新到底。、
注意:给的X Y大小未知,会出现X > Y的情况
*************************************************************************
#pragma comment(linker, "/STACK:102400000,102400000")
#include<algorithm>
#include<stdio.h>
#include< string.h>
#include<math.h>
using  namespace std;

#define Lson root<<1,L,tree[root].Mid()
#define Rson root<<1|1,tree[root].Mid()+1,R

const  int maxn =  100005;

struct Tree
{
     int L, R;
     long  long sum;
     int Mid(){ return (L+R)/ 2;}
     int Len(){ return (R-L+ 1);}
}tree[maxn* 4];
long  long val[maxn];

void Build( int root,  int L,  int R)
{
    tree[root].L = L, tree[root].R = R;

     if(L == R)
    {
        tree[root].sum = val[L];
         return ;
    }

    Build(Lson);
    Build(Rson);

    tree[root].sum = tree[root<< 1].sum + tree[root<< 1| 1].sum;
}
void Insert( int root,  int L,  int R)
{
     if(tree[root].Len() == tree[root].sum)
         return ;
     if(tree[root].L == tree[root].R)
    {
        tree[root].sum = ( long  long)sqrt(tree[root].sum* 1.0);
         return ;
    }

     if(R <= tree[root].Mid())
        Insert(root<< 1, L, R);
     else  if(L > tree[root].Mid())
        Insert(root<< 1| 1, L, R);
     else
    {
        Insert(Lson);
        Insert(Rson);
    }

    tree[root].sum = tree[root<< 1].sum + tree[root<< 1| 1].sum;
}
long  long Query( int root,  int L,  int R)
{
     if(tree[root].L == L && tree[root].R == R)
         return tree[root].sum;

     if(R <= tree[root].Mid())
         return Query(root<< 1, L, R);
     else  if(L > tree[root].Mid())
         return Query(root<< 1| 1, L, R);
     else
         return Query(Lson)+Query(Rson);
}

int main()
{
     int i, N, M, t= 1;

     while(scanf( " %d ", &N) != EOF)
    {
         for(i= 1; i<=N; i++)
            scanf( " %lld ", &val[i]);
        Build( 11, N);

        scanf( " %d ", &M);

         int c, a, b;
         long  long ans;

        printf( " Case #%d:\n ", t++);
         while(M--)
        {
            scanf( " %d%d%d ", &c, &a, &b);
             if(a > b)swap(a, b);
             if(c ==  0)
                Insert( 1, a, b);
             else
            {
                ans = Query( 1, a, b);
                printf( " %lld\n ", ans);
            }
        }
        printf( " \n ");
    }

     return  0;  

}

 

你可能感兴趣的:(you)