hdu 4027 Can you answer these queries? -线段树

xiaoxiao2021-02-28  79

题目链接 :点击打开链接

题目要求开根那么再大的一个数不超过十次开根就会变成1,那么此时就不需要再更新了,所以用线段树只需特判这个点就可以了。

题解:

#include<iostream> #include<algorithm> #include<cstdio> #include<cstring> #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 using namespace std; typedef long long ll; const int mx=100010; int n,m; ll sum[mx<<2]; void push_up(int rt){ sum[rt]=sum[rt<<1]+sum[rt<<1|1]; } void build(int l,int r,int rt){ if(l==r){ scanf("%lld",sum+rt); return ; } int m=(l+r)>>1; build(lson); build(rson); push_up(rt); } void update(int l,int r,int rt,int L,int R){ if(sum[rt]==r-l+1) return ; if(l==r){ sum[rt]=sqrt(sum[rt]); return ; } int m=(l+r)>>1; if(L<=m) update(lson,L,R); if(R>m) update(rson,L,R); push_up(rt); } ll query(int l,int r,int rt,int L,int R){ if(l>=L&&R>=r) return sum[rt]; int m=(l+r)>>1; ll ans=0; if(L<=m) ans+=query(lson,L,R); if(R>m) ans+=query(rson,L,R); return ans; } int main(){ int cases=1; while(cin>>n){ build(1,n,1); int q,x,y,t; scanf("%d",&q); printf("Case #%d:\n",cases++); while(q--){ scanf("%d%d%d",&t,&x,&y); if(x>y) swap(x,y); if(t){ printf("%lld\n",query(1,n,1,x,y)); }else{ update(1,n,1,x,y); } } puts(""); } return 0; }

转载请注明原文地址: https://www.6miu.com/read-35840.html

最新回复(0)