您的位置:首页 > 产品设计 > UI/UE

HDU 4027 Can you answer these queries?(线段树,区间更新,区间查询)

2014-05-11 20:33 120 查看
题目

线段树

简单题意:

区间(单点?)更新,区间求和

更新是区间内的数开根号并向下取整
这道题不用延迟操作

//注意:
//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|1

LL 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;
}


View Code

虽然我自己不会写线段树,但是以后遇到 区间(单点?)更新,区间求和,这可以当底板修改一下就可以用了,毕竟这里的用法还是蛮好理解的
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐