Spoj 2713 Can you answer these queries IV 水线段树

简介:

题目链接:点击打开链接

题意:

给定n长的序列

以下2个操作

0 x y 给[x,y]区间每一个数都 sqrt

1 x y 问[x, y] 区间和

#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <string.h>
#include <queue>
#include <math.h>
#include <vector>
#include <set>
using namespace std;
#define ll long long
#define N 100005
#define L(x) tree[x].l
#define R(x) tree[x].r
#define Lson(x) (x<<1)
#define Rson(x) (x<<1|1)
#define Num(x) tree[x].num
#define Sum(x) tree[x].sum
inline int Mid(int x, int y){return (x+y)>>1;}
struct Subtree{
    int l, r;
    ll num, sum;
}tree[N<<2];
ll a[N];
void push_up(int id){
    if(L(id) == R(id))return;
    Sum(id) = Sum(Lson(id)) + Sum(Rson(id));
    if(Num(Lson(id)) <= 1  && Num(Rson(id)) <= 1)
        Num(id) = 1;
    else Num(id) = 2;
}
void build(int l, int r, int id){
    L(id) = l; R(id) = r;
    if(l == r) { Num(id) = Sum(id) = a[l]; return ;}
    int mid = Mid(l, r);
    build(l, mid, Lson(id));
    build(mid+1, r, Rson(id));
    push_up(id);
}
void updata(int l, int r, int id){
    if(L(id) == R(id))
    {
        Sum(id) = Num(id) = (ll)sqrt((double)Sum(id));
        return ;
    }
    if(l == L(id) && R(id) == r && Num(id) <= 1) return ;

    int mid = Mid(L(id), R(id));
    if(mid < l)
        updata(l, r, Rson(id));
    else if(r <= mid)
        updata(l, r, Lson(id));
    else {
        updata(l, mid, Lson(id));
        updata(mid+1, r, Rson(id));
    }
    push_up(id);
}
ll query(int l, int r, int id){
    if(l == L(id) && R(id) == r)
        return Sum(id);
    int mid = Mid(L(id), R(id));
    if(mid < l)
        return query(l, r, Rson(id));
    else if(r <= mid)
        return query(l, r, Lson(id));
    else return query(l, mid, Lson(id)) + query(mid+1, r, Rson(id));
}
int n;
void solve(){
    int q, op, x, y;
    for(int i = 1; i <= n; i++)scanf("%lld", &a[i]);
    build(1, n, 1);
    scanf("%d",&q);
    while(q--){
        scanf("%d %d %d", &op, &x, &y);
        if(x > y) swap(x, y);
        if(op == 0)
            updata(x, y, 1);
        else
            printf("%lld\n", query(x, y, 1));
    }
}
int main(){
    int Cas = 1;
	while(~scanf("%d", &n)){
        printf("Case #%d:\n", Cas++);
        solve();
        puts("");
	}
	return 0;
}






本文转自mfrbuaa博客园博客,原文链接:http://www.cnblogs.com/mfrbuaa/p/5198479.html,如需转载请自行联系原作者
相关文章
|
开发框架 .NET
poj 3468 A Simple Problem with Integers线段树区间修改
题目意思很简单,有N个数,Q个操作, Q l r 表示查询从l到r 的和,C l r v 表示将从l到r 的值加上v,明显的线段树,不知道线段树的人肯定暴力,肯定超时,哈哈!!
34 0
|
人工智能 vr&ar
SPOJ - COT Count on a tree(主席树 LCA)
SPOJ - COT Count on a tree(主席树 LCA)
99 0
AtCoder Beginner Contest 216 G - 01Sequence (并查集 贪心 树状数组 差分约束)
AtCoder Beginner Contest 216 G - 01Sequence (并查集 贪心 树状数组 差分约束)
154 0
AtCoder Beginner Contest 216 D - Pair of Balls (思维建图 拓扑排序判断有向图是否有环)
AtCoder Beginner Contest 216 D - Pair of Balls (思维建图 拓扑排序判断有向图是否有环)
126 0
|
人工智能
[Codeforces 1579G] Minimal Coverage | dp最小区间覆盖
题意: 给出n个线段,以及一个无限大的坐标轴,第一个线段以0为起点进行放置,后面的线段必须以前一个的终点为起点放置,这就有两种方式,向左向右
|
Go
HDOJ/HDU 1085 Holding Bin-Laden Captive!(非母函数求解)
HDOJ/HDU 1085 Holding Bin-Laden Captive!(非母函数求解)
115 0
|
Java C语言
HDOJ/HDU 1029 Ignatius and the Princess IV(简单DP,排序)
HDOJ/HDU 1029 Ignatius and the Princess IV(简单DP,排序)
142 0
[转]POJ3624 Charm Bracelet(典型01背包问题)
来源:https://www.cnblogs.com/jinglecjy/p/5674796.html 题目链接:http://bailian.openjudge.cn/practice/4131/ Time Limit: 1000MS          Memory Limit: 65536K  ...
1238 0
|
Java Windows
HDU 1005 Number Sequence【多解,暴力打表,鸽巢原理】
Number Sequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 175657    Accepted Submission...
871 0