HDU 4027 Can you answer these queries? 线段树裸题

来源:互联网 发布:万科荣华金域名城地址 编辑:程序博客网 时间:2024/04/27 13:25

题意:

给定2个操作

0、把区间的每个数sqrt

2、求和

因为每个数的sqrt次数很少,所以直接更新到底,用个标记表示是否更新完全(即区间内的数字只有0,1就不用再更新了)

#include<stdio.h>#include<iostream>#include<algorithm>#include<vector>#include<cmath>#include<queue>#include<set>#include<map>using namespace std;#define N 1000000#define L(x) (x<<1)#define R(x) (x<<1|1)#define Val(x) tree[x].val#define Ned(x) tree[x].ned#define ll __int64inline ll Mid(ll x,ll y){return (x+y)>>1;}struct node{ll l, r;ll val;//这个区间需要被sqrt几次bool ned;//如果为true则表示这个区间不管怎么开结果都一样}tree[N*4];ll n, a[101000];void push_up(ll id){Ned(id) = Ned(L(id))&&Ned(R(id));Val(id) = Val(L(id))+Val(R(id));}void build(ll l, ll r, ll id){tree[id].l = l; tree[id].r = r;Ned(id) = false;if(l==r){ Val(id) = a[l]; if(Val(id)<=1)Ned(id)=true; return ;}ll mid = Mid(l,r);build(l, mid, L(id));build(mid+1,r,R(id));push_up(id);}void update(ll l, ll r, ll id){if(Ned(id))return;if(l == tree[id].l && tree[id].r == r && l==r){Val(id) = (ll)sqrt(1.0*Val(id));if(Val(id)<=1)Ned(id)=1;return;}ll mid = Mid(tree[id].l, tree[id].r);if(r<=mid)update(l,r,L(id));else if(mid<l)update(l,r,R(id));else{update(l,mid,L(id));update(mid+1,r,R(id));}push_up(id);}ll query(ll l, ll r, ll id){if(tree[id].l == tree[id].r)return Val(id);if(l == tree[id].l && tree[id].r == r && Ned(id))return Val(id);ll mid = Mid(tree[id].l, tree[id].r);if(r<=mid)return query(l,r,L(id));else if(mid<l)return query(l,r,R(id));else return query(l,mid,L(id))+query(mid+1,r,R(id));}int main(){ll u, v, i, que, Cas = 1;while(~scanf("%I64d",&n)){for(i=1;i<=n;i++)scanf("%I64d",&a[i]);build(1,n,1);scanf("%I64d",&que);printf("Case #%I64d:\n",Cas++);while(que--){scanf("%I64d %I64d %I64d",&i,&u,&v);if(u>v)swap(u,v);if(i==0)update(u,v,1);elseprintf("%I64d\n",query(u,v,1));}puts("");}return 0;}/* 101 2 3 4 5 6 7 8 9 10991 10 100 2 8*/


0 0
原创粉丝点击