没查找一次开方一次,每个点最多8次就不变了。
ACcode:
#include<stdio.h>
#include<math.h>
#include<iostream>
#define LL __int64
using namespace std;
const int size=111111;
__int64 sum[size<<2];
int flag[size<<2];
void PushUp(int rt)
{
flag[rt]=flag[rt<<1]&flag[rt<<1|1];
sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
void build(int rt,int l,int r)
{
if (l==r)
{
scanf("%I64d",&sum[rt]);
if (sum[rt]>1) flag[rt]=0;
else flag[rt]=1;
return ;
}
int m=(l+r)>>1;
build(rt<<1,l,m);
build(rt<<1|1,m+1,r);
PushUp(rt);
}
void update(int rt,int l,int r,int L,int R)
{
if (flag[rt]) return ;
if (l==r)
{
sum[rt]=(LL)(sqrt((double)sum[rt]));
if (sum[rt]>1) flag[rt]=0;
else flag[rt]=1;
return ;
}
int m=(l+r)>>1;
if ((!flag[rt<<1])&&(L<=m)) update(rt<<1,l,m,L,R);
if ((!flag[rt<<1|1])&&(R>m)) update(rt<<1|1,m+1,r,L,R);
PushUp(rt);
}
LL query(int rt,int l,int r,int L,int R)
{
if (L<=l&&r<=R) return sum[rt];
int m=(l+r)>>1;
LL ans=0;
if (L<=m) ans+=query(rt<<1,l,m,L,R);
if (R>m) ans+=query(rt<<1|1,m+1,r,L,R);
return ans;
}
int main()
{
int n,q,x,y,op,cas=0;
while (~scanf("%d",&n))
{
build(1,1,n);
scanf("%d",&q);
printf("Case #%d:\n",++cas);
while(q--)
{
scanf("%d %d %d",&op,&x,&y);
if (x>y) swap(x,y);
if (!op) update(1,1,n,x,y);
else
{
LL tmp=query(1,1,n,x,y);
printf("%I64d\n",tmp);
}
}
puts("");
}
return 0;
}