前几天做 div 2的时候卡在这题上了,线段树不会实在是伤啊,学了几天线段树后,今晚就敲了发。
思路 : 类似于区间涂颜色(只要倒着涂即可),每一个节点的保存的信息是 : 如果这个节点所代表的的区间都是同一种颜色则fg[rt] != 0,否则fg[rt]为0。
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 300005;
#define lson rt<<1, l, mid
#define rson rt<<1|1, mid + 1, r
int fg[maxn<<2], n, m;
int s[maxn], e[maxn], c[maxn];
void push_down(int rt)
{
if (fg[rt])
{
fg[rt<<1] = fg[rt<<1|1] = fg[rt];
fg[rt] = 0;
}
return ;
}
void push_up(int rt)
{
if (fg[rt<<1] == fg[rt<<1|1])
fg[rt] = fg[rt<<1];
else fg[rt] = 0;
}
void update(int rt, int l, int r, int L, int R, int col)
{
if (l >= L && r <= R)
{
fg[rt] = col;
return ;
}
push_down(rt);
int mid = (l + r) >> 1;
if (mid >= L)update(lson, L, R, col);
if (R > mid)update(rson, L, R, col);
push_up(rt);
}
void print(int rt, int l, int r)
{
if (r == l)
{
printf("%d ",fg[rt]);
return ;
}
if (fg[rt])
{
for (int i = l; i <= r; i++) printf("%d ",fg[rt]);
return ;
}
int mid = (l + r) >> 1;
print(lson);
print(rson);
}
int main()
{
scanf("%d%d",&n,&m);
memset(fg,0,sizeof(fg));
for (int i = m; i >= 1; i--)
scanf("%d%d%d",&s[i],&e[i],&c[i]);
for (int i = 1; i <= m; i++)
{
if (c[i] > s[i]) update(1, 1, n, s[i], c[i]-1, c[i]);
if (c[i] < e[i]) update(1, 1, n, c[i]+1, e[i], c[i]);
}
print(1, 1, n);
printf("\n");
return 0;
}