您的位置:首页 > 理论基础 > 数据结构算法

Donut Decoration

2016-07-09 13:19 363 查看

Solution & Code

题意是用 1...K 共 K 种颜色对一行共 N 个点染色,现给你染色的操作序列(按时间先后给定),每次操作对 [l,r] 区间的所有点染上一种颜色 x,求所有操作完成后,共有多少个点合法(恰按序被染上 1...K 这些颜色)。

这道题用带标记的线段树处理,对每个线段树节点记录三个标记:当前染色上界(lazy1)、当前染色下界(lazy2)、当前点及其儿子是否已经不合法(des),详见代码。

#include <cstdio>
#include <algorithm>
#include <iostream>
using namespace std;

const int maxn = 4e5 + 5;

int n, k, m, ans;

struct segment_tree{

int tot;
struct node{
int lazy1, lazy2, lson, rson; bool des;
}nd[maxn];

#define ls nd[i].lson
#define rs nd[i].rson

int build(int left, int rght){
int i = ++tot;
if(left != rght){
int mid = (left + rght) >> 1;
ls = build(left, mid);
rs = build(mid + 1, rght);
}
nd[i].lazy1 = nd[i].lazy2 = 0;
nd[i].des = false;
return i;
}
void pushdown(int i){
if(!ls && !rs) return;
if(nd[ls].lazy1 == 0) nd[ls].lazy1 = nd[i].lazy1, nd[ls].lazy2 = nd[i].lazy2;
else if(nd[ls].lazy2 + 1 == nd[i].lazy1) nd[ls].lazy2 = nd[i].lazy2;
else nd[ls].des = true;
if(nd[rs].lazy1 == 0) nd[rs].lazy1 = nd[i].lazy1, nd[rs].lazy2 = nd[i].lazy2;
else if(nd[rs].lazy2 + 1 == nd[i].lazy1) nd[rs].lazy2 = nd[i].lazy2;
else nd[rs].des = true;
nd[i].lazy1 = nd[i].lazy2 = 0;
}
void modify(int i, int left, int rght, int x, int y, int z){
if(nd[i].des) return;
if(nd[i].lazy1) pushdown(i);
if(x <= left && rght <= y){
if(!nd[i].lazy1) nd[i].lazy1 = nd[i].lazy2 = z;
else if(nd[i].lazy2 + 1 == z) nd[i].lazy2 = z;
else nd[i].des = true;
return;
}
int mid = (left + rght) >> 1;
if(ls && x <= mid) modify(ls, left, mid, x, y, z);
if(rs && y >  mid) modify(rs, mid + 1, rght, x, y, z);
}
void shake(int i, int left, int rght){
if(nd[i].des) nd[ls].des = nd[rs].des = true;
if(nd[i].lazy1) pushdown(i);
if(!ls && !rs){
if(nd[i].des) return;
if(nd[i].lazy1 != 1) return;
if(nd[i].lazy2 != k) return;
++ans;
}
int mid = (left + rght) >> 1;
if(ls) shake(ls, left, mid);
if(rs) shake(rs, mid + 1, rght);
}
}st;

int main(){

scanf("%d%d", &n, &k);
scanf("%d", &m);
st.build(1, n);
for(int i = 1; i <= m; ++i){
int x, y, z;
scanf("%d%d%d", &x, &y, &z);
st.modify(1, 1, n, x, y, z);
}
st.shake(1, 1, n);
printf("%d\n", ans);

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  数据结构 线段树