bzoj 4364: [IOI2014]wall砖墙
2017-10-01 16:09
253 查看
题意:
维护一段序列,可以将区间所有小于h的改为h,大于h的改为h。题解:
最假女选手?!这数据范围分块炸裂。
偷听一波知道是线段树。
考虑维护最大最小值,那么对当前节点的修改就很好写的。
关键是怎么将标记下传。
一开始,我想打上处于那种状态(op=1或2)
然后发现不太正确。
既然一个标记不行,那么就上两个嘛。
分成op1,op2,表示两种操作。
于是好像就可行了。
貌似还有一个问题,操作似乎是有顺序的。
但认真思考一下,可以发现是无所谓的,因为父亲节点已经保存了当前这段区间的上下界。
code:
#include<cstdio> #include<cstdlib> #include<cstring> #include<iostream> using namespace std; struct trnode{ int lc,rc,max,min,op1,op2; }tr[4000010];int tot=0; int read() { int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } int bt(int l,int r) { int x=++tot; if(l!=r) { int mid=(l+r)/2; tr[x].lc=bt(l,mid); tr[x].rc=bt(mid+1,r); } return x; } void mymin(int &x,int y){x=min(x,y);} void mymax(int &x,int y){x=max(x,y);} void pushdown(int x) { int c,lc=tr[x].lc,rc=tr[x].rc; if(tr[x].op2!=0) { mymin(tr[lc].max,tr[x].max);mymin(tr[lc].min,tr[x].max); mymin(tr[rc].max,tr[x].max);mymin(tr[rc].min,tr[x].max); tr[lc].op2=tr[rc].op2=1; } if(tr[x].op1!=0) { mymax(tr[lc].max,tr[x].min);mymax(tr[lc].min,tr[x].min); mymax(tr[rc].max,tr[x].min);mymax(tr[rc].min,tr[x].min); tr[lc].op1=tr[rc].op1=1; } tr[x].op1=tr[x].op2=0; } void update(int x,int h,int op) { if(op==1) { mymax(tr[x].max,h); mymax(tr[x].min,h); } else { mymin(tr[x].max,h); mymin(tr[x].min,h); } } void change(int x,int l,int r,int fl,int fr,int h,int op) { if(fl==l&&r==fr) { update(x,h,op); if(op==1) tr[x].op1=1; else tr[x].op2=1; return; } if(tr[x].op1!=0||tr[x].op2!=0) pushdown(x); int mid=(l+r)/2; if(fr<=mid) change(tr[x].lc,l,mid,fl,fr,h,op); else if(fl>mid) change(tr[x].rc,mid+1,r,fl,fr,h,op); else change(tr[x].lc,l,mid,fl,mid,h,op),change(tr[x].rc,mid+1,r,mid+1,fr,h,op); tr[x].max=max(tr[tr[x].lc].max,tr[tr[x].rc].max); tr[x].min=min(tr[tr[x].lc].min,tr[tr[x].rc].min); } void print(int x,int l,int r) { if(l==r){printf("%d\n",tr[x].max);return;} pushdown(x); int mid=(l+r)/2; print(tr[x].lc,l,mid);print(tr[x].rc,mid+1,r); } int main() { int n,m;n=read();m=read(); bt(1,n); while(m--) { int op,l,r,h;op=read();l=read();r=read();h=read(); change(1,1,n,l+1,r+1,h,op); } print(1,1,n); }
相关文章推荐
- bzoj 4364: [IOI2014]wall砖墙 线段树
- bzoj 4364: [IOI2014]wall砖墙
- [BZOJ]4364: [IOI2014]wall砖墙 线段树
- 4364: [IOI2014]wall砖墙
- bzoj4364: [IOI2014]wall砖墙
- bzoj5053 [ioi2014]Phidias 菲迪亚斯神
- 【IOI2014】【BZOJ4367】holiday假期
- [bzoj4356][ceoi2014] wall
- [UOJ 25] [IOI 2014] Wall 【线段树】
- BZOJ4367 IOI2014holiday假期(整体二分+主席树)
- [BZOJ4367][IOI2014]Holiday(决策单调性+分治+主席树)
- 【BZOJ4367】[IOI2014]holiday假期 分治+主席树
- [bzoj4367][IOI2014]holiday假期
- [决策单调性 分治 主席树] BZOJ 4367 [IOI2014]holiday假期
- BZOJ 4367 [IOI2014]holiday假期 分治 主席树
- [最短路 杂题] BZOJ 4356 Ceoi2014 Wall
- [IOI2014]Wall
- BZOJ 4356 Ceoi2014 Wall
- 【IOI2014】bzoj4367 holiday
- [UOJ 25][IOI2014]Wall(裸线段树)