[线段树] Luogu P4560 砖墙

题目描述

给定一个长度为 nn且初始值全为 00的序列。你需要支持以下两种操作:

  • Add L, R, hL,R,h:将序列 [L, R][L,R]内所有值小于 hh的元素都赋为 hh,此时不改变高度大于 hh的元素值
  • Remove L, R, hL,R,h:将序列 [L, R][L,R]内所有值大于 hh的元素都赋为 hh,此时不改变高度小于 hh的元素值

你需要输出进行 kk次上述操作之后的序列。

输入输出格式

输入格式:

 

输入的第一行包含两个正整数 n, kn,k,分别表示序列中元素的个数以及操作数量,注意:序列下标编号为 00 ~ n-1n1。

接下来 kk行每行包含 44个整数 t, L, R, ht,L,R,h,若 t = 1t=1则表明为 Add 操作,若 t = 2t=2则表明为 Remove 操作。 L, R, hL,R,h的含义见题目描述。

 

输出格式:

 

输出包含 nn行,每行包含 11个整数。第 ii行的整数表示 kk次操作之后序列中编号为 i - 1i1的元素的值。

 

输入输出样例

输入样例#1:
10 3
1 3 4 91220
1 5 9 48623
2 3 5 39412
输出样例#1:
0
0
0
39412
39412
39412
48623
48623
48623
48623
输入样例#2:
10 6
1 1 8 4
2 4 9 1
2 3 6 5
1 0 5 3
1 2 2 5
2 6 7 0
输出样例#2: 
3
4
5
4
3
3
0
0
1
0

说明

  • 子任务#1(8分):满足 1 \leq n \leq 10 000, 1 \leq k \leq 5 0001n10000,1k5000;
  • 子任务#2(24分):满足 1 \leq n \leq 100 000, 1 \leq k \leq 500 0001n100000,1k500000,全部增加操作均在全部移除操作之前;
  • 子任务#3(29分):满足 1 \leq n \leq 100 000, 1 \leq k \leq 500 0001n100000,1k500000;
  • 子任务#4(39分):满足 1 \leq n \leq 2 000 000, 1 \leq k \leq 500 0001n2000000,1k500000。

所有操作的高度 hh满足 0 \leq h \leq 100 0000h100000。

 

题解

  • 就是对区间取min和取max,比较简单的一道线段树

题解

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 #define N 2000010
 5 using namespace std;
 6 int n,m;
 7 struct Tree
 8 {
 9     int mx[N*4],mn[N*4];
10     void Max(int x,int y) { mn[x]=max(mn[x],y),mx[x]=max(mx[x],y); }
11     void Min(int x,int y) { mn[x]=min(mn[x],y),mx[x]=min(mx[x],y); } 
12     void pushdown(int d) { Max(d*2,mx[d]),Max(d*2+1,mx[d]),Min(d*2,mn[d]),Min(d*2+1,mn[d]),mx[d]=0,mn[d]=0x7fffffff; }    
13     void update(int d,int L,int R,int l,int r,int x,int y)
14     {
15         if (L<=l&&r<=R) { if (y==0) Max(d,x); else Min(d,x); return; }
16         int mid=l+r>>1;
17         pushdown(d);
18         if (L<=mid) update(d*2,L,R,l,mid,x,y);
19         if (R>mid) update(d*2+1,L,R,mid+1,r,x,y);
20     } 
21     void query(int d,int l,int r)
22     {
23         if (l==r) { printf("%d\n",mx[d]); return; }
24         int mid=l+r>>1;
25         pushdown(d),query(d*2,l,mid),query(d*2+1,mid+1,r);
26     }    
27 }tree;
28 int main()
29 {
30     scanf("%d%d",&n,&m);
31     for (int i=1;i<=n*4;i++) tree.mn[i]=0x7fffffff;
32     for (int i=1,op,l,r,h;i<=m;i++) scanf("%d%d%d%d",&op,&l,&r,&h),tree.update(1,l+1,r+1,1,n,h,op-1);
33     tree.query(1,1,n);
34 } 

 

posted @ 2019-07-17 10:09  BEYang_Z  阅读(137)  评论(0编辑  收藏  举报