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; }
相关文章推荐
- C#数据结构之顺序表(SeqList)实例详解
- Lua教程(七):数据结构详解
- 解析从源码分析常见的基于Array的数据结构动态扩容机制的详解
- C#数据结构之队列(Quene)实例详解
- C#数据结构揭秘一
- C#数据结构之单链表(LinkList)实例详解
- 数据结构之Treap详解
- 用C语言举例讲解数据结构中的算法复杂度结与顺序表
- C#数据结构之堆栈(Stack)实例详解
- C#数据结构之双向链表(DbLinkList)实例详解
- JavaScript数据结构和算法之图和图算法
- Java数据结构及算法实例:冒泡排序 Bubble Sort
- Java数据结构及算法实例:插入排序 Insertion Sort
- Java数据结构及算法实例:考拉兹猜想 Collatz Conjecture
- java数据结构之java实现栈
- java数据结构之实现双向链表的示例
- Java数据结构及算法实例:选择排序 Selection Sort
- Java数据结构及算法实例:朴素字符匹配 Brute Force
- Java数据结构及算法实例:汉诺塔问题 Hanoi
- Java数据结构及算法实例:快速计算二进制数中1的个数(Fast Bit Counting)