题意 输入n个数 然后有两种操作 输入0时将给定区间所有数都变为自己的开方 输入1输出给定区间所有数的和
虽然是区间更新 但每个点更新的不一样 因此只能对单点进行更新 其实一个点最多被更新7次 2^64开平方7次后就变为1了 如果某个区间的数都变为了1 那么对这个区间的开方就不用考虑了 另外要注意给你的区间可能是反的
#include <bits/stdc++.h>
#define lc p<<1,s,mid
#define rc p<<1|1,mid+1,e
#define mid ((s+e)>>1)
using namespace std;
typedef long long LL;
const int N = 100005;
LL sum[N * 4];
void pushup(int p)
{
sum[p] = sum[p << 1] + sum[p << 1 | 1];
}
void build(int p, int s, int e)
{
if(s == e)
{
scanf("%lld", &sum[p]);
return;
}
build(lc);
build(rc);
pushup(p);
}
void update(int p, int s, int e, int l, int r)
{
if(sum[p] == e - s + 1) return; //[e,s]区间所有数都为1
if(s == e)
{
sum[p] = sqrt(sum[p]);
return;
}
if(l <= mid) update(lc, l, r);
if(r > mid) update(rc, l, r);
pushup(p);
}
LL query(int p, int s, int e, int l, int r)
{
if(s == l && e == r) return sum[p];
if(r <= mid) return query(lc, l, r);
if(l > mid) return query(rc, l, r);
return query(lc, l, mid) + query(rc, mid + 1, r);
}
int main()
{
int n, m, a, b, c, k = 0;
while(~scanf("%d", &n))
{
printf("Case #%d:\n", ++k);
build(1, 1, n);
scanf("%d", &m);
while(m--)
{
scanf("%d%d%d", &c, &a, &b);
if(b < a) swap(a, b);
if(c) printf("%lld\n", query(1, 1, n, a, b));
else update(1, 1, n, a, b);
}
puts("");
}
return 0;
}
10 1 2 3 4 5 6 7 8 9 10 5 0 1 10 1 1 10 1 1 5 0 5 8 1 4 8
Case #1: 19 7 6
HDU 4027 Can you answer these queries?(线段树 区间不等更新)
原文地址:http://blog.csdn.net/acvay/article/details/45126499