http://acm.hust.edu.cn/vjudge/contest/view.action?cid=66989#problem/H
这一题要注意剪枝,所有不必访问的点都不需要再访问了,注意最小的值不是0而是1;
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <stack>
#include <cmath>
#include <string>
#define SI(T)int T;scanf("%d",&T)
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define LL long long
using namespace std;
const int SIZE=1e5+10;
const int maxn=1<<30;
__int64 sum[SIZE<<2];
void pushup(int rt){
sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
void build(int l,int r,int rt){
if(l==r){
scanf("%I64d",&sum[rt]);
return;
}
int m=(l+r)>>1;
build(lson);
build(rson);
pushup(rt);
}
void update(int L,int R,int l,int r,int rt){
if(sum[rt]==r-l+1)return;
if(l==r){
sum[rt]=(__int64)sqrt(sum[rt]);
return;
}
int m=(l+r)>>1;
if(L<=m)update(L,R,lson);
if(R>m)update(L,R,rson);
pushup(rt);
}
__int64 query(int L,int R,int l,int r,int rt){
if(L<=l&&r<=R){
return sum[rt];
}
if(sum[rt]==1)return 1;
int m=(l+r)>>1;
__int64 ans=0;
if(L<=m)ans+=query(L,R,lson);
if(R>m)ans+=query(L,R,rson);
return ans;
}
int main()
{
int n,m,t,x,y,cas=1;
while(scanf("%d",&n)!=EOF){
printf("Case #%d:\n",cas++);
build(1,n,1);
scanf("%d",&m);
while(m--){
scanf("%d%d%d",&t,&x,&y);
if(x>y)swap(x,y);
if(t==0){
update(x,y,1,n,1);
}
else printf("%I64d\n",query(x,y,1,n,1));
}
printf("\n");
}
return 0;
}