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

时间:2023-03-09 22:59:45
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 = ; struct Tree
{
    int L, R;
    long long sum;
    int Mid(){return (L+R)/;}
    int Len(){return (R-L+);}
}tree[maxn*];
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<<].sum + tree[root<<|].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<<, L, R);
    else if(L > tree[root].Mid())
        Insert(root<<|, L, R);
    else
    {
        Insert(Lson);
        Insert(Rson);
    }     tree[root].sum = tree[root<<].sum + tree[root<<|].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<<, L, R);
    else if(L > tree[root].Mid())
        return Query(root<<|, L, R);
    else
        return Query(Lson)+Query(Rson);
} int main()
{
    int i, N, M, t=;     while(scanf("%d", &N) != EOF)
    {
        for(i=; i<=N; i++)
            scanf("%lld", &val[i]);
        Build(, , 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 == )
                Insert(, a, b);
            else
            {
                ans = Query(, a, b);
                printf("%lld\n", ans);
            }
        }
        printf("\n");
    }     return ; }