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(1, 1, 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;

}

时间: 2024-10-12 15:24:29

H - Can you answer these queries? - (区间查询更新)的相关文章

H - Can you answer these queries? HDU 4027 (线段树+延迟标记+开根号的速度)

H - Can you answer these queries? Time Limit:2000MS Memory Limit:65768KB 64bit IO Format:%I64d & %I64u Submit Status Practice HDU 4027 Description A lot of battleships of evil are arranged in a line before the battle. Our commander decides to use our

HDU 4027 Can you answer these queries?(线段树,区间更新,区间查询)

题目 线段树 简单题意: 区间(单点?)更新,区间求和 更新是区间内的数开根号并向下取整 这道题不用延迟操作 //注意: //1:查询时的区间端点可能前面的比后面的大: //2:优化:因为每次更新都是开平方,同一个数更新有限次数就一直是1了,所以可以这样优化 #include <stdio.h> #include<math.h> #define N 100010 #define LL __int64 #define lson l,m,rt<<1 #define rson

HDU 4027 Can you answer these queries?(线段树的单点更新+区间查询)

题目链接 题意 : 给你N个数,进行M次操作,0操作是将区间内的每一个数变成自己的平方根(整数),1操作是求区间和. 思路 :单点更新,区间查询,就是要注意在更新的时候要优化,要不然会超时,因为所有的数开几次方之后都会变成1,所以到了1不用没完没了的更新. 1 //HDU 4027 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #include <iostream> 6 #defi

HDU 4027 Can you answer these queries?(线段树/区间不等更新)

传送门 Can you answer these queries? Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65768/65768 K (Java/Others)Total Submission(s): 18290    Accepted Submission(s): 4308 Description A lot of battleships of evil are arranged in a line before the

HDU4027——线段树成段更新——Can you answer these queries?

A lot of battleships of evil are arranged in a line before the battle. Our commander decides to use our secret weapon to eliminate the battleships. Each of the battleships can be marked a value of endurance. For every attack of our secret weapon, it

HDU 4027 Can you answer these queries?(线段树 区间不等更新)

题意  输入n个数  然后有两种操作   输入0时将给定区间所有数都变为自己的开方   输入1输出给定区间所有数的和 虽然是区间更新  但每个点更新的不一样  因此只能对单点进行更新  其实一个点最多被更新7次  2^64开平方7次后就变为1了  如果某个区间的数都变为了1  那么对这个区间的开方就不用考虑了   另外要注意给你的区间可能是反的 #include <bits/stdc++.h> #define lc p<<1,s,mid #define rc p<<1|

SPOJ GSS2 - Can you answer these queries II(线段树 区间修改+区间查询)(后缀和)

GSS2 - Can you answer these queries II #tree Being a completist and a simplist, kid Yang Zhe cannot solve but get Wrong Answer from most of the OI problems. And he refuse to write two program of same kind at all. So he always failes in contests. When

GSS - Can you answer these queries I ~ ? (持续更新...)

GSS - Can you answer these queries I ~ ? (持续更新...) \(\text{SPOJ}\) 毒瘤的 数据结构系列, 值得一做 GSS I : 给定一数列\(A\), 支持查询区间最大子段和 \(A[i] \le 15007,\ N\le 5e4\) 线段树常规做法 : //知识点:线段树 /* By:Luckyblock */ #include <cstdio> #include <cctype> #include <algorith

HDU 4027 Can you answer these queries(线段树 成段更新)

Problem Description A lot of battleships of evil are arranged in a line before the battle. Our commander decides to use our secret weapon to eliminate the battleships. Each of the battleships can be marked a value of endurance. For every attack of ou