您的位置:首页 > 其它

2017金马五校赛 M.风力观测(线段树)

2017-07-12 23:20 344 查看
题目传送门

思路:闲来无事补补题,看到这道题貌似是线段树,感觉自己能做出来,在打完初代代码加上无数遍的debug之后,终于让我过了



这题的主要难点在求历史风力最大绝对值,所以要把风力变化的最大值(正方向最大值)和最小值(负方向最大值)记录下来(下面都以最大值最小值来解释)。这里直接单点更新应该是会超时的(我也没试过,不过这种成段更新的,应该是不能这样处理),所以要延迟更新。我这里用lazy来记录风力的变化量,然后用flag标记是否需要向下更新。主要问题就在这个更新上面,这里不只更新了lazy,还更新了当前层变化量的最大值和最小值。

用案例来说明:1 1 5 1(1到5的风力正方向+1)



(节省时间,随意画了一下_(:зゝ∠)_)

在多次更新的时候

更新序号变化值
1-4
22
3-1
415
5-4
比如最大值出现在第四次更新,当发生延迟更新时,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))

更新的具体实现如下面代码

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));
}
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐