2017金马五校赛 M.风力观测(线段树)
2017-07-12 23:20
344 查看
题目传送门
思路:闲来无事补补题,看到这道题貌似是线段树,感觉自己能做出来,在打完初代代码加上无数遍的debug之后,终于让我过了
这题的主要难点在求历史风力最大绝对值,所以要把风力变化的最大值(正方向最大值)和最小值(负方向最大值)记录下来(下面都以最大值最小值来解释)。这里直接单点更新应该是会超时的(我也没试过,不过这种成段更新的,应该是不能这样处理),所以要延迟更新。我这里用lazy来记录风力的变化量,然后用flag标记是否需要向下更新。主要问题就在这个更新上面,这里不只更新了lazy,还更新了当前层变化量的最大值和最小值。
用案例来说明:1 1 5 1(1到5的风力正方向+1)
(节省时间,随意画了一下_(:зゝ∠)_)
在多次更新的时候
比如最大值出现在第四次更新,当发生延迟更新时,1和2先更新,所以lazy=-2,maxw=0,minw=-4;
3和4更新的lazy=14,maxw=14,minw=-1。
3和4合并的更新再向下更新就是lazy=-2+14 , maxw=max(0,-2+14) , minw=min(-4,-2+(-1))
更新的具体实现如下面代码
感觉解释不清楚。。。还是先看代码吧
等我想清楚了再更新
下面是代码:
思路:闲来无事补补题,看到这道题貌似是线段树,感觉自己能做出来,在打完初代代码加上无数遍的debug之后,终于让我过了
这题的主要难点在求历史风力最大绝对值,所以要把风力变化的最大值(正方向最大值)和最小值(负方向最大值)记录下来(下面都以最大值最小值来解释)。这里直接单点更新应该是会超时的(我也没试过,不过这种成段更新的,应该是不能这样处理),所以要延迟更新。我这里用lazy来记录风力的变化量,然后用flag标记是否需要向下更新。主要问题就在这个更新上面,这里不只更新了lazy,还更新了当前层变化量的最大值和最小值。
用案例来说明:1 1 5 1(1到5的风力正方向+1)
(节省时间,随意画了一下_(:зゝ∠)_)
在多次更新的时候
更新序号 | 变化值 |
---|---|
1 | -4 |
2 | 2 |
3 | -1 |
4 | 15 |
5 | -4 |
3和4更新的lazy=14,maxw=14,minw=-1。
3和4合并的更新再向下更新就是lazy=-2+14 , maxw=max(0,-2+14) , minw=min(-4,-2+(-1))
更新的具体实现如下面代码
void updatelazy(int t)//更新 { p[t*2].flag=p[t*2+1].flag=true;//标记需要向下更新 p[t*2].maxw=max(p[t*2].maxw,p[t].maxw+p[t*2].lazy); p[t*2+1].maxw=max(p[t*2+1].maxw,p[t].maxw+p[t*2+1].lazy); p[t*2].minw=min(p[t*2].minw,p[t].minw+p[t*2].lazy); p[t*2+1].minw=min(p[t*2+1].minw,p[t].minw+p[t*2+1].lazy); p[t*2].lazy+=p[t].lazy; p[t*2+1].lazy+=p[t].lazy; p[t].flag=false; p[t].maxw=p[t].minw=p[t].lazy=0; }
感觉解释不清楚。。。还是先看代码吧
等我想清楚了再更新
下面是代码:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define N 100005 using namespace std; struct point{ int l,r; int maxw,minw; int lazy; bool flag; }p[N*4]; int n,q; int a ; void build(int t,int l,int r) { p[t].l=l; p[t].r=r; p[t].maxw=p[t].minw=p[t].lazy=0; p[t].flag=false; if(l==r) return; int mid=(l+r)/2; build(t*2,l,mid); build(t*2+1,mid+1,r); } void updatelazy(int t) { p[t*2].flag=p[t*2+1].flag=true; p[t*2].maxw=max(p[t*2].maxw,p[t].maxw+p[t*2].lazy); p[t*2+1].maxw=max(p[t*2+1].maxw,p[t].maxw+p[t*2+1].lazy); p[t*2].minw=min(p[t*2].minw,p[t].minw+p[t*2].lazy); p[t*2+1].minw=min(p[t*2+1].minw,p[t].minw+p[t*2+1].lazy); p[t*2].lazy+=p[t].lazy; p[t*2+1].lazy+=p[t].lazy; p[t].flag=false; p[t].maxw=p[t].minw=p[t].lazy=0; } void update(int t,int l,int r,int lazy) { int lc=p[t].l; int rc=p[t].r; int mid=(lc+rc)/2; if(lc>=l&&rc<=r) { p[t].flag=true; p[t].lazy+=lazy; p[t].maxw=max(p[t].maxw,p[t].lazy); p[t].minw=min(p[t].minw,p[t].lazy); return; } if(p[t].flag) updatelazy(t); if(mid>=r) update(t*2,l,r,lazy); else if(mid<l) update(2*t+1,l,r,lazy); else update(2*t,l,mid,lazy),update(2*t+1,mid+1,r,lazy); } int query(int t,int x) { int lc=p[t].l; int rc=p[t].r; int mid=(lc+rc)/2; if(lc==rc) return max(abs(p[t].maxw+a[x]),abs(p[t].minw+a[x])); if(p[t].flag) updatelazy(t); if(mid>=x) return query(t*2,x); else return query(2*t+1,x); } int main() { int T; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&q); for(int i=1;i<=n;i++) scanf("%d",&a[i]); build(1,1,n); while(q--) { int type,x,y,z; scanf("%d",&type); if(type==1) { scanf("%d%d%d",&x,&y,&z); update(1,x,y,z); } else { scanf("%d",&x); printf("%d\n",query(1,x)); } } } }
相关文章推荐
- SHU-“盛大游戏杯”第15届上海大学程序设计联赛夏季赛暨上海高校金马五校赛-M-风力观测
- “盛大游戏杯”第15届上海大学程序设计联赛夏季赛暨上海高校金马五校赛 M SHUOJ 422 风力观测
- 2017 山理校赛 线段树单点更新+状压
- SHU 422 风力观测 (线段树,区间更新,区间询问历史最大值)
- SHU oj 422 风力观测 线段树
- 2017金马五校赛 F.A序列(LIS)
- 【“盛大游戏杯”第15届上海大学程序设计联赛 M】【线段树 时间维度线段树 前缀和标记 离线询问】风力观测 历史最大值
- "盛大游戏杯" M 风力观测 (线段树)
- SHUOJ-422 风力观测(线段树)
- “盛大游戏杯”第15届上海大学程序设计联赛夏季赛暨上海高校金马五校赛 E
- 2017 icpc亚洲区预赛西安站 K Lover || (线段树)
- HAUT 1262 魔法宝石(spfa)(河南工业大学2017校赛)
- HAUT 1266 最大子段和(类似DP)(河南工业大学2017校赛)
- 2017河南工业大学校赛 C 魔法宝石
- zzuli 2130: hipercijevi bfs+输入输出外挂 (2017轻工业校赛 )
- ACM-ICPC国际大学生程序设计竞赛北京赛区(2017)网络赛 题目9 : Minimum(线段树)
- 北理2017校赛 - B.XC的缎带 - 排序+贪心
- hdu 6070 Dirt Ratio(二分+线段树)(2017 Multi-University Training Contest - Team 4 )
- [线段树 杂题] Codeforces 806E VK Cup 2017 Round 3 E. Blog Post Rating
- 【jzoj5248】【NOIP2017提高A组模拟8.10】【花花的聚会】【动态规划】【可持久化线段树】