题目
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
#define lc (o<<1)
#define rc (o<<1|1)
#define mid (l+r>>1)
const int N=1e5+10;
typedef long long ll;
ll sum[N<<2],lazy[N<<2];
inline void push_up(int o)
{
sum[o]=sum[lc]+sum[rc];
}
void build(int o,int l,int r)
{
if(l==r)
{
scanf("%lld",&sum[o]);
return;
}
build(lc,l,mid);build(rc,mid+1,r);
push_up(o);
}
void update(int o,int l,int r,int nl,int nr)
{
if(l==r)
{
sum[o]=sqrt(sum[o]);
return;
}
if(nl<=l&&r<=nr&&sum[o]==r-l+1)return;
if(nl<=mid)update(lc,l,mid,nl,nr);
if(nr>mid)update(rc,mid+1,r,nl,nr);//此处不要加else...
push_up(o);
}
ll query(int o,int l,int r,int nl,int nr)
{
if(nl<=l&&r<=nr)return sum[o];
ll ans=0;
if(nl<=mid)ans+=query(lc,l,mid,nl,nr);
if(nr>mid)ans+=query(rc,mid+1,r,nl,nr);
return ans;
}
int main()
{
//freopen("in.txt","r",stdin);
int n,m,ca=0;
while(~scanf("%d",&n))
{
memset(sum,0,sizeof(sum));
memset(lazy,0,sizeof(lazy));
printf("Case #%d:\n",++ca);
build(1,1,n);
int m,op,x,y;
scanf("%d",&m);
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&op,&x,&y);
if(x>y)swap(x,y);
if(op==0)
update(1,1,n,x,y);
else
printf("%lld\n",query(1,1,n,x,y));
}
printf("\n");
}
return 0;
}
总结
基础的线段树。