[BZOJ3211]花神游历各国(线段树)
2017-01-29 19:36
471 查看
题目描述
传送门题解
同上帝造题的七分钟2区间修改全部下放到叶子节点
对于开方到0或1不用再修改的点打标记
代码
#include<algorithm> #include<iostream> #include<cstring> #include<cstdio> #include<cmath> using namespace std; #define LL long long #define N 100005 int n,m,opt,l,r; LL a ,sum[N*4],ans; bool flag[N*4]; void update(int now) { sum[now]=sum[now<<1]+sum[now<<1|1]; flag[now]=flag[now<<1]&&flag[now<<1|1]; } void build(int now,int l,int r) { int mid=(l+r)>>1; if (l==r) { sum[now]=a[l]; if (sum[now]==0||sum[now]==1) flag[now]=1; return; } build(now<<1,l,mid); build(now<<1|1,mid+1,r); update(now); } void change(int now,int l,int r,int lr,int rr) { int mid=(l+r)>>1; if (l==r) { sum[now]=(LL)sqrt(sum[now]); if (sum[now]==0||sum[now]==1) flag[now]=1; return; } if (lr<=mid&&!flag[now<<1]) change(now<<1,l,mid,lr,rr); if (mid+1<=rr&&!flag[now<<1|1]) change(now<<1|1,mid+1,r,lr,rr); update(now); } LL query(int now,int l,int r,int lr,int rr) { int mid=(l+r)>>1; LL ans=0; if (lr<=l&&r<=rr) return sum[now]; if (lr<=mid) ans+=query(now<<1,l,mid,lr,rr); if (mid+1<=rr) ans+=query(now<<1|1,mid+1,r,lr,rr); return ans; } int main() { scanf("%d",&n); for (int i=1;i<=n;++i) scanf("%lld",&a[i]); build(1,1,n); scanf("%d",&m); for (int i=1;i<=m;++i) { scanf("%d%d%d",&opt,&l,&r); if (l>r) swap(l,r); if (opt==1) { ans=query(1,1,n,l,r); printf("%lld\n",ans); } else change(1,1,n,l,r); } }
相关文章推荐
- 【线段树/区间开平方】BZOJ3211-花神游历各国
- BZOJ 3211 花神游历各国 线段树
- bzoj3211 花神游历各国 线段树
- BZOJ 3211-花神游历各国(线段树)
- [BZOJ3211]花神游历各国(线段树+区间开根)
- BZOJ 3211(花神游历各国-线段树区间开方)
- 花神游历各国 bzoj3211 线段树
- [bzoj3211]花神游历各国 线段树
- BZOJ 3211 花神游历各国 树状数组(线段树)+优化
- bzoj3211花神游历各国 线段树
- BZOJ 题目3211: 花神游历各国(线段树区间减为平方根,区间求和)
- bzoj3211 花神游历各国(线段树)
- 树线段BZOJ 3211(花神游历各国-线段树区间开方)
- BZOJ 3211 花神游历各国 - 线段树
- 【BZOJ 3211】花神游历各国 &【 线段树区间开根】
- BZOJ 3211: 花神游历各国( 线段树 )
- BZOJ 3211: 花神游历各国【线段树区间开方问题】
- BZOJ3038 && BZOJ3211 上帝造题的七分钟2 && 花神游历各国 (线段树 + 开方标记)
- 【BZOJ3211】花神游历各国(线段树)
- BZOJ 3211: 花神游历各国(势能分析线段树)