【线段树/区间开平方】BZOJ3211-花神游历各国
2016-03-08 19:00
274 查看
【题目大意】
给出一些数,有两种操作。(1)将区间内每一个数开方(2)查询每一段区间的和
【思路】
普通的线段树保留修改+开方优化。可以知道当一个数为0或1时,无论开方几次,答案仍然相同。所以设置flag=1。如果一个节点的左右孩子flag均为1,那么它的flag也是1。
给出一些数,有两种操作。(1)将区间内每一个数开方(2)查询每一段区间的和
【思路】
普通的线段树保留修改+开方优化。可以知道当一个数为0或1时,无论开方几次,答案仍然相同。所以设置flag=1。如果一个节点的左右孩子flag均为1,那么它的flag也是1。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define LL long long using namespace std; const int MAXN=100000+500; int n,m; LL sum[MAXN<<2]; int flag[MAXN<<2]; void pushup(int rt) { sum[rt]=sum[rt<<1]+sum[rt<<1|1]; flag[rt]=flag[rt<<1]&flag[rt<<1|1]; } void build(int l,int r,int rt) { flag[rt]=0; if (l==r) { scanf("%lld",&sum[rt]); return; } int m=(l+r)>>1; build(lson); build(rson); pushup(rt); } void update(int L,int R,int l,int r,int rt) { if (flag[rt]) return; if (l==r) { sum[rt]=(LL)sqrt(sum[rt]); if (sum[rt]==0 || sum[rt]==1) flag[rt]=1; return; } int m=(l+r)>>1; if (L<=m) update(L,R,lson); if (R>m) update(L,R,rson); pushup(rt); } LL query(int L,int R,int l,int r,int rt) { if (L<=l && r<=R) return sum[rt]; int m=(l+r)>>1; LL ret=0; if (L<=m) ret+=query(L,R,lson); if (R>m) ret+=query(L,R,rson); return ret; } int main() { scanf("%d",&n); build(1,n,1); scanf("%d",&m); for (int i=0;i<m;i++) { int x,l,r; scanf("%d%d%d",&x,&l,&r); if (x==1) printf("%lld\n",query(l,r,1,n,1)); else update(l,r,1,n,1); } return 0; }
相关文章推荐
- Codeforces Problem - 617B Chocolate
- 微信公众号编辑模式应用
- 用户代码未处理 UpdateException
- 彻底理解js中this的指向
- c++ 一次读取文件全部内容
- 【Codeforces Round 345 (Div 1) A】【STL-map or stable_sort or双关键字排序】Watchmen 曼哈顿距离=欧几里得距离点对数
- zjnu1716 NEKAMELEONI (线段树)
- redis在mac上的安装
- Codeforces Round #345 (Div. 2) C (multiset+pair )
- 上海微博签到系统
- Python学习之:打印输出同一行
- 正则表达式
- 【2015-2016 XVI Open CupL】【找规律】Liesbeth and the String 字符串变换何时变为长度1
- 关于独立按键与矩阵按键的程序(51单片机)
- ios 真机调试时出现CopyPngFile error解决方法
- Android Toast
- 规定元素的高度,宽度
- Java的多态——看程序时自动带感
- online_judge_1385
- C/C++面试常见的几个库函数详解(strcpy,memcpy,memset,atoi...)