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

hdu 4027 Can you answer these queries?

2012-11-29 01:12 302 查看
题意:给你N个数,有M个操作,操作有两类,(1)"0 l r",表示将区间[l,r]里的每个数都开根号。(2)"1 l r",表示查询区间[l,r]里所有数的和。

虽然题目给出的数的范围达到了2^63次方,但是,最多开根号7次就会变成1。所以在每次更新的时候,判断,如果这个区间里的所有数被开根号的次数大于7,就不用再往下更新了,其次,因为每个数最多只会有7次开根号,所以在更新的时,可以一直更新到叶子结点。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;

#define LL(x) (x<<1)
#define RR(x) (x<<1|1)
#define MID(a,b) (a+((b-a)>>1))
const int N=100005;
typedef long long LL;

struct node
{
int lft,rht;
LL cnt,sum;
int mid(){return MID(lft,rht);}
int len(){return rht-lft+1;}
};

int n,m;
LL y
;

struct Segtree
{
node tree[N*4];
void up(int ind)
{
tree[ind].sum=tree[LL(ind)].sum+tree[RR(ind)].sum;
if(tree[LL(ind)].cnt>=7&&tree[RR(ind)].cnt>=7)
tree[ind].cnt=7;
}
void build(int lft,int rht,int ind)
{
tree[ind].lft=lft;    tree[ind].rht=rht;
tree[ind].cnt=0;    tree[ind].sum=0;
if(lft==rht) tree[ind].sum=y[lft];
else
{
int mid=tree[ind].mid();
build(lft,mid,LL(ind));
build(mid+1,rht,RR(ind));
tree[ind].sum=tree[LL(ind)].sum+tree[RR(ind)].sum;
}
}
void updata(int st,int ed,int ind)
{
if(tree[ind].cnt>=7)
{
tree[ind].sum=tree[ind].len();
return;
}

int lft=tree[ind].lft,rht=tree[ind].rht;
if(st<=lft&&rht<=ed)
{
tree[ind].cnt+=1;
if(lft==rht)
tree[ind].sum=(int)sqrt(tree[ind].sum*1.0);
else
{
updata(st,ed,LL(ind));
updata(st,ed,RR(ind));
up(ind);
}
}

else
{
int mid=tree[ind].mid();
if(st<=mid) updata(st,ed,LL(ind));
if(ed> mid) updata(st,ed,RR(ind));
up(ind);
}
}
LL query(int st,int ed,int ind)
{
int lft=tree[ind].lft,rht=tree[ind].rht;
if(st<=lft&&rht<=ed) return tree[ind].sum;
else
{
int mid=tree[ind].mid();
LL sum1=0,sum2=0;
if(st<=mid) sum1=query(st,ed,LL(ind));
if(ed> mid) sum2=query(st,ed,RR(ind));
return sum1+sum2;
}
}
}seg;
int main()
{
int t_cnt=0;
while(scanf("%d",&n)!=EOF)
{
for(int i=1;i<=n;i++) scanf("%I64d\n",&y[i]);
scanf("%d",&m);

seg.build(1,n,1);

printf("Case #%d:\n",++t_cnt);
for(int i=0;i<m;i++)
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
if(b>c) swap(b,c);
if(a==0) seg.updata(b,c,1);
else printf("%I64d\n",seg.query(b,c,1));
}
puts("");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: