Can you answer these queries?(线段树之单点更新)

萌萌哒的传送门

因为一个long long 范围内的数开方不会超过10次,所以题目就转化为线段树的单点更新问题.

#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <set>
#include <queue>
#include <vector>
#include <cstdlib>
#include <algorithm>

#define ls u << 1
#define rs u << 1 | 1
#define lson l, mid, u << 1
#define rson mid + 1, r, u << 1 | 1
#define INF 0x3f3f3f3f

using namespace std;
typedef long long ll;
const int M = 1e5 + 100;
const int N = 1e7 + 100;
ll sum[M << 2];

void pushup(int u){
    sum[u] = sum[ls] + sum[rs];
}

void build(int l,int r,int u){
    if(l == r){
        scanf("%I64d",sum + u);
    }
    else {
        int mid = (l + r) >> 1;
        build(lson);
        build(rson);
        pushup(u);
    }
}

void update(int L,int R,int l,int r,int u){
    if(sum[u] == (r - l + 1)){
        return;
    }
    if(l == r){
        sum[u] = floor(sqrt((double)sum[u]));
    }
    else {
        int mid = (l + r) >> 1;
        if(L <= mid) update(L,R,lson);
        if(R > mid) update(L,R,rson);
        pushup(u);
    }
}

ll query(int L,int R,int l,int r,int u){
    if(L <= l && R >= r){
        return sum[u];
    }
    else {
        int mid = (l + r) >> 1;
        ll res = 0;
        if(L <= mid) res += query(L,R,lson);
        if(R > mid) res += query(L,R,rson);
        return res;
    }
}

int main(){
    //freopen("in","r",stdin);
    int n,m,cnt = 0;
    while(~scanf("%d",&n)){
        build(1,n,1);
        scanf("%d",&m);
        printf("Case #%d:\n",++cnt);
        while(m--){
            int t,l,r;
            scanf("%d %d %d",&t,&l,&r);
            if(l > r) swap(l,r);
            if(!t) update(l,r,1,n,1);
            else {
                printf("%I64d\n",query(l,r,1,n,1));
            }
        }
        puts("");
    }
    return 0;
}
时间: 2024-08-06 14:33:23

Can you answer these queries?(线段树之单点更新)的相关文章

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

HDU4027 Can you answer these queries 线段树区间求和+剪枝

给了你n,然后n个数字在一个数组中,接下来m个询问,每个询问三个数字 t,x,y,若t==0,那么修改区间[x,y]的每一个值,变为原来每个位置上的数 开根号取整,若t==1,那么对区间[x,y]求和 由于n,m,很大,所以树状数组铁定超时,若直接用线段树来做区间修改,那么也是超时,这类题目没别的方法了,静心剪枝,发现题目给的数据范围为2^63,有没有发现,2^63开根号 绝对不需要开10次,就能到1,到1以后就不需要再开了,意思就是若有某个区间[x,y]每一个点的值都为1时,这一段区间事实上是

HDU 4027 Can you answer these queries? (线段树+区间点修改)

题意:给你 n 个数,m个询问(c,x,y) c==0 把x,y区间的值变为原来的平方根(向下取整) c==1 计算x,y区间的和. 利用1的开方永远为1剪枝.. #include<cstdio> #include<stdlib.h> #include<string.h> #include<string> //#include<map> #include<cmath> #include<iostream> #include

HDU 4027 Can you answer these queries? 线段树裸题

题意: 给定2个操作 0.把区间的每个数sqrt 2.求和 因为每个数的sqrt次数很少,所以直接更新到底,用个标记表示是否更新完全(即区间内的数字只有0,1就不用再更新了) #include<stdio.h> #include<iostream> #include<algorithm> #include<vector> #include<cmath> #include<queue> #include<set> #incl

hdu4027-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): 8330    Accepted Submission(s): 1904 Problem Description A lot of battleships of evil are arranged in a line before

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 3074-Multiply game(线段树:单点更新,区间求积)

Multiply game Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1450    Accepted Submission(s): 508 Problem Description Tired of playing computer games, alpc23 is planning to play a game on numbe

线段树 基础单点更新 敌兵布阵

题:敌兵布阵 标准线段树模板代码: #include<cstdio> #include<cstring> const int maxn = 500000 + 10; struct Node{ int left, right, count; }node[maxn]; int a[maxn]; /*********************************** ***************建树**************** ************i是区间序号********