Can you answer these queries?-HDU4027 区间开方
题意:
给你n个数,两个操作,0为区间开方,1为区间求和
链接:http://acm.hdu.edu.cn/showproblem.php?pid=4027
思路:
如果当该区间的数都为1,我们没必要进行开方操作,因为1开方还是1,否则找到每个叶子节点,进行开方操作
代码:
#include <iostream> #include <algorithm> #include <cmath> #include <cstdio> #include <cstdlib> using namespace std; const int MAXN=1e5+5; const int INF=0x7fffffff; typedef long long ll; ll lazy[MAXN<<2],tree[MAXN<<2]; void push_up(int node) { tree[node]=tree[node<<1]+tree[node<<1|1]; } void build(int node,int l,int r) { if(l==r) { scanf("%lld",&tree[node]); return ; } int mid=(l+r)>>1; build(node<<1,l,mid); build(node<<1|1,mid+1,r); push_up(node); } void update(int node,int l,int r,int x,int y) { //区间的长度等于区间内所有数之和则说明所有数都为1 if(x<=l&&y>=r&&(r-l+1==tree[node])) { return; } if(l==r) { tree[node]=(ll)sqrt(tree[node]);return; } int mid=(l+r)>>1; if(x<=mid) update(node<<1,l,mid,x,y); if(y>mid) update(node<<1|1,mid+1,r,x,y); push_up(node); } ll query(int node,int l,int r,int x,int y) { if(x<=l&&y>=r) { return tree[node]; } ll ans=0; int mid=(l+r)>>1; if(x<=mid)ans+=query(node<<1,l,mid,x,y); if(y>mid)ans+=query(node<<1|1,mid+1,r,x,y); return ans; } int main() { int n; int case_=0; while(scanf("%d",&n)!=EOF) { printf("Case #%d:\n",++case_); build(1,1,n); int k;scanf("%d",&k); for(int i=1;i<=k;i++) { int op;scanf("%d",&op); int x,y; if(!op) { scanf("%d%d",&x,&y);update(1,1,n,min(x,y),max(x,y)); } else { scanf("%d%d",&x,&y); printf("%lld\n",query(1,1,n,min(x,y),max(x,y))); } }printf("\n"); } return 0; }