此题同 HDU4027 http://acm.hdu.edu.cn/showproblem.php?pid=4027
题意:给定的数组,进行两种操作,
操作一:求出给定区间的和 操作二:对于给定区间的数,求出对应的平方根~~~
题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=26684
思路:
如果单点更新,由于操作范围是区间,必然超时,也就被区间的假象迷惑,果断的tle,,,看大牛的讲解,对于给定的数的范围,最多平方7次,也就变成1,也就是说,区间更新可以做成定点更新,加上标记,如果变成了1,那么这个区间不再发生改变,解决~~~~
#include <iostream>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define maxn 100010
#define LL long long
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
LL sum[maxn<<2];
bool col[maxn<<2];
void PushUp(int rt){
sum[rt] = sum[rt<<1] + sum[rt<<1|1];
col[rt] = col[rt<<1] || col[rt<<1|1];
}
void build(int l,int r,int rt){
if(l == r){
scanf("%lld",&sum[rt]);
col[rt] = 1;
return ;
}
int m = (l + r)/2;
build(lson);
build(rson);
PushUp(rt);
}
void update(int L,int R,int l,int r,int rt){
if(!col[rt] && L <= l && r <= R) return ;
if(l == r){
sum[rt] = (LL) sqrt(sum[rt]);
if(sum[rt]== 1 || sum[rt] == 0) col[rt] = 0;
return ;
}
int m = (l + r)/2;
if(L <= m) update(L,R,lson);
if(m < R) update(L,R,rson);
PushUp(rt);
}
LL query(int L,int R,int l,int r,int rt){
if(L <= l && r <= R) {
return sum[rt];
}
int m = (l + r)/2;
LL ret = 0;
if(L <= m) ret += query(L,R,lson);
if(m < R) ret += query(L,R,rson);
return ret;
}
int n,m,a,b,op;
int main(){
int ncase = 1;
while(~scanf("%d",&n)){
build(1,n,1);
printf("Case #%d:\n",ncase++);
scanf("%d",&m);
while(m--){
scanf("%d %d %d",&op,&a,&b);
if(a>b) swap(a,b);
if(op == 0) update(a,b,1,n,1);
else printf("%lld\n",query(a,b,1,n,1));
}
printf("\n");
}
return 0;
}