线段树
简单题意:
区间(单点?)更新,区间求和
更新是区间内的数开根号并向下取整
这道题不用延迟操作
//注意:
//1:查询时的区间端点可能前面的比后面的大;
//2:优化:因为每次更新都是开平方,同一个数更新有限次数就一直是1了,所以可以这样优化
#include <stdio.h>
#include<math.h>
#define N 100010#define LL __int64
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1LL sum[N<<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(l==r)
{
sum[rt]=(__int64)sqrt((double)sum[rt]);
return;
}
int m=(l+r)>>1;
if(L<=m)
Update(L,R,lson);
if(R>m)
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)>>1;
LL ret=0;
if(L<=m) ret+=Query(L,R,lson);
if(R>m) ret+=Query(L,R,rson);
return ret;
}int main()
{
int m,n,id=1;
LL anss;
while(scanf("%d",&n)!=EOF)
{
Build(1,n,1);
scanf("%d",&m);
printf("Case #%d:\n",id++);
while(m--)
{
int q,a,b,c;
scanf("%d%d%d",&q,&a,&b);
if(a>b)
{
c=a;
a=b;
b=c;
}anss=Query(a,b,1,n,1);
if(q==1)
{
printf("%I64d\n",anss);
}
else
{
if(anss != b-a+1)
Update(a,b,1,n,1);
}
}
printf("\n");
}
return 0;
}
虽然我自己不会写线段树,但是以后遇到 区间(单点?)更新,区间求和,这可以当底板修改一下就可以用了,毕竟这里的用法还是蛮好理解的
HDU 4027 Can you answer these queries?(线段树,区间更新,区间查询),布布扣,bubuko.com