[ZOJ1610]Count the Colors(线段树,区间染色,单点查询)
2016-05-14 10:54
453 查看
题目链接:http://www.icpc.moe/onlinejudge/showProblem.do?problemCode=1610
题意:给一个长8000的绳子,向上染色。一共有n段被染色,问染色后共有多少不同的色段。注意假如相邻两个线段同色,那么算作一条线段。
线段树区间更新,不需要pushUP操作,因为查询和非叶节点无关。找长线段的时候首先定位最靠左那根,然后判后面是否与前面的线段颜色相等。注意有可能出现两条线段中间没有染色的情况,这时候查询返回一个无关值,这时候重置p即可。
题意:给一个长8000的绳子,向上染色。一共有n段被染色,问染色后共有多少不同的色段。注意假如相邻两个线段同色,那么算作一条线段。
线段树区间更新,不需要pushUP操作,因为查询和非叶节点无关。找长线段的时候首先定位最靠左那根,然后判后面是否与前面的线段颜色相等。注意有可能出现两条线段中间没有染色的情况,这时候查询返回一个无关值,这时候重置p即可。
#include <algorithm> #include <iostream> #include <iomanip> #include <cstring> #include <climits> #include <complex> #include <fstream> #include <cassert> #include <cstdio> #include <bitset> #include <vector> #include <deque> #include <queue> #include <stack> #include <ctime> #include <set> #include <map> #include <cmath> using namespace std; #define fr first #define sc second #define pb(a) push_back(a) #define Rint(a) scanf("%d", &a) #define Rll(a) scanf("%I64d", &a) #define Rs(a) scanf("%s", a) #define Fread() freopen("in", "r", stdin) #define Fwrite() freopen("out", "w", stdout) #define Rep(i, n) for(int i = 0; i < (n); i++) #define For(i, a, n) for(int i = (a); i < (n); i++) #define Cls(a) memset((a), (0), sizeof(a)) #define Clr(a, x) memset((a), (x), sizeof(a)) #define Full(a) memset((a), 0x7f7f, sizeof(a)) #define lson l, m, rt << 1 #define rson m + 1, r, rt << 1 | 1 const int maxn = 8010; int sum[maxn<<2]; int vis[maxn]; int n, a, b, c; void pushDOWN(int rt) { if(sum[rt] != -1) { sum[rt<<1] = sum[rt<<1|1] = sum[rt]; sum[rt] = -1; } } void update(int L, int R, int c, int l, int r, int rt) { if(L <= l && r <= R) { sum[rt] = c; return; } pushDOWN(rt); int m = (l + r) >> 1; if(L <= m) update(L, R, c, lson); if(R > m) update(L, R, c, rson); } int query(int p, int l, int r, int rt) { if(l == r) { return sum[rt]; } pushDOWN(rt); int m = (l + r) >> 1; if(p <= m) return query(p, lson); else return query(p, rson); } int main() { // Fread(); while(~Rint(n)) { int lo = 0x7f7f; Clr(sum, -1); Cls(vis); Rep(i, n) { Rint(a), Rint(b), Rint(c); lo = min(lo, a+1); update(a+1, b, c, 1, 8000, 1); } int p = query(lo, 1, 8000, 1); vis[p]++; For(i, lo+1, 8001) { int t = query(i, 1, 8000, 1); if(t == -1) { p = -1; continue; } if(t != p) { vis[t]++; p = t; } } Rep(i, 8001) { if(vis[i]) printf("%d %d\n", i, vis[i]); } printf("\n"); } return 0; }
相关文章推荐
- 个人学习心得笔记之java中"=="
- cojs 简单的求和问题 解题报告
- [sql]复制表数据
- IDEA在编辑时提示could not autowire
- 微信群九大规律 - 47万微信群和2亿微信用户背后的故事
- datatables.js 简单使用--多选框和服务器端分页
- 【LeetCode】290. Word Pattern
- 背包问题
- php变量后加中括号
- iOS开发中APP共享数据之UIPasteboard使用
- MySQL(24):事务的隔离级别
- 离骚
- LeetCode|Game of Life
- Electron.js折腾记(一):getStart
- CI框架中pdo的使用方法
- 【BZOJ-1017】魔兽地图DotR 树形DP + 背包
- leetcode 092 Reverse Linked List II
- word2vec (二) CBOW
- java-反射初学(2)
- Move Zeroes