zoj 1610 线段树

来源:互联网 发布:淘宝客服上哪儿应聘 编辑:程序博客网 时间:2024/05/22 12:54

题目链接:点击打开链接

大概意思就是给一个区间,然后多次操作给各个子区间涂色,颜色可覆盖,问最后各个颜色的区间有几段;

哇,线段树的又一种写法诶,dog,dog;

(神经病啊)

#include<iostream>#include<algorithm>#include<string>#include<queue>#include<cmath>#include<vector>#include<stdlib.h>#include<iomanip>#include<list>#include<stack>#include<memory.h>#include<ctype.h>using namespace std;typedef long long ll;const int maxn = 8000 + 5;struct node{int l, r;int color;};node tree[maxn*3];int color[maxn];//计数数组void init(int l, int r, int pos) {tree[pos].l = l;tree[pos].r = r;tree[pos].color = -1;//-1表示没有颜色if (l == r - 1) return;int mid = (l + r) >> 1;init(l, mid, pos << 1);init(mid, r, pos << 1 | 1);}void updata(int pos, int l, int r, int val) {//更新区间l-r的信息,pos:节点位置,val:颜色if (l == r)return;if (tree[pos].color == val)return;if (l <= tree[pos].l&&r >= tree[pos].r) {tree[pos].color = val;return;}if (tree[pos].color >= 0) {//存在颜色,标记下推tree[pos << 1].color = tree[pos].color;tree[pos << 1|1].color = tree[pos].color;tree[pos].color =-2;//该节点已经下推过,标记清空}int mid = (tree[pos].l + tree[pos].r) >> 1;if (r <= mid)updata(pos << 1, l, r, val);else if (l >= mid)updata(pos << 1 | 1, l, r, val);else {updata(pos << 1, l, mid, val);updata(pos << 1 | 1, mid, r, val);}tree[pos].color = -2;//该节点不需要再下推}int temp;void count(int pos) {//统计各颜色的段数if (tree[pos].color == -1) {temp = -1;return;}if (tree[pos].color != -2) {if (tree[pos].color != temp) {color[tree[pos].color]++;temp = tree[pos].color;//temp保存前一段的颜色}return;}if (tree[pos].l != tree[pos].r - 1) {count(pos << 1);count(pos << 1 | 1);}}int main() {int n, a, b, c;int num;while (scanf("%d", &n) != EOF) {init(0,8000, 1);num = 0;while (n--) {scanf("%d%d%d", &a, &b, &c);updata(1, a, b, c);if (c > num)num = c;}temp = -1;//temp初始化memset(color, 0, sizeof(color));count(1);for (int i = 0; i <= num; i++) {if (color[i])printf("%d %d\n", i, color[i]);}printf("\n");}return 0;}


原创粉丝点击