(Relax 线段树1.4)POJ 3225 Help with Intervals

本文详细解析了一段C++代码的功能,包括其核心内容、关键信息及运行时环境的处理策略。通过代码实例,展示了如何利用C++进行特定任务的实现,并讨论了代码中涉及的数据结构和算法应用。


/*
 * POJ_3225.cpp
 *
 *  Created on: 2013年11月25日
 *      Author: Administrator
 */

#include <iostream>
#include <cstdio>

#define maxn 140000
#define Fup(i, s, t) for (int i = s; i <= t; i ++)
#define Fdn(i, s, t) for (int i = s; i >= t; i --)

using namespace std;

struct node {
	int val, mark;
} tree[maxn * 4];
int pos[maxn + 10];

void update_reverse(int i) {
	if (!tree[i].mark)
		return;
	if (tree[i + i].val != -1)
		tree[i + i].val = 1 - tree[i + i].val;
	else
		tree[i + i].mark = (tree[i + i].mark + 1) % 2;
	if (tree[i + i + 1].val != -1)
		tree[i + i + 1].val = 1 - tree[i + i + 1].val;
	else
		tree[i + i + 1].mark = (tree[i + i + 1].mark + 1) % 2;
	tree[i].mark = 0;
}

void update(int i) {
	if (tree[i].val == -1)
		return;
	tree[i + i].val = tree[i + i + 1].val = tree[i].val;
}

void change(int tl, int tr, int l, int r, int i, int v) {
	if (tl > tr)
		return;
	if (tl > r || tr < l)
		return;
	if (tl <= l && r <= tr) {
		tree[i].val = v;
		return;
	}
	update_reverse(i);
	update(i);
	int mid = (l + r) / 2;
	change(tl, tr, l, mid, i + i, v);
	change(tl, tr, mid + 1, r, i + i + 1, v);
	if (tree[i + i].val != tree[i + i + 1].val || tree[i + i].val == -1)
		tree[i].val = -1;
	else
		tree[i].val = tree[i + i].val;
}

void reverse(int tl, int tr, int l, int r, int i) {
	if (tl > tr)
		return;
	if (tl > r || tr < l)
		return;
	int mid = (l + r) / 2;
	if (tl <= l && r <= tr) {
		if (tree[i].val == -1)
			tree[i].mark = (tree[i].mark + 1) % 2;
		else
			tree[i].val = 1 - tree[i].val;
		return;
	}
	update_reverse(i);
	update(i);
	reverse(tl, tr, l, mid, i + i);
	reverse(tl, tr, mid + 1, r, i + i + 1);
	if (tree[i + i].val != tree[i + i + 1].val || tree[i + i].val == -1)
		tree[i].val = -1;
	else
		tree[i].val = tree[i + i].val;
}

void check_tree(int l, int r, int i) {
	if (l == r) {
		pos[l] = i;
		return;
	}
	update_reverse(i);
	update(i);
	int mid = (l + r) / 2;
	check_tree(l, mid, i + i);
	check_tree(mid + 1, r, i + i + 1);
}

int main() {
	char kind, tc1, tc2, lf, rf;
	int l, r;

	memset(tree,0,sizeof(tree));

	//每当第一个是字符的时候,都要特别注意,看看是不是存在读取的问题..
	while (scanf(" %c%c%c%d%c%d%c", &kind, &tc1, &lf, &l, &tc2, &r, &rf) == 7) {
		l = l * 2;
		r = r * 2;

		if (lf == '(') {
			l++;
		}

		if (rf == ')') {
			--r;
		}

		switch (kind) {
		case 'U':
			change(l, r, 0, maxn, 1, 1);
			break;
		case 'I':
			change(0, l - 1, 0, maxn, 1, 0);
			change(r + 1, maxn, 0, maxn, 1, 0);
			break;
		case 'D':
			change(l, r, 0, maxn, 1, 0);
			break;
		case 'C':
			change(0, l - 1, 0, maxn, 1, 0);
			change(r + 1, maxn, 0, maxn, 1, 0);
			reverse(l, r, 0, maxn, 1);
			break;
		case 'S':
			reverse(l, r, 0, maxn, 1);
			break;
		}
	}

	check_tree(0, maxn, 1);
	bool flag = 0;
	bool have = 0;

	int i;
	for (i = 0; i < maxn; ++i) {
		if (tree[pos[i]].val) {
			if (!flag) {
				flag = 1;
				if (have) {
					printf(" ");
				}

				if (i % 2 == 0) {
					printf("[");
				} else {
					printf("(");
				}

				printf("%d,", i / 2);
			}

			have = 1;
		} else {
			if (flag) {
				printf("%d", i / 2);
				if (i % 2 == 1) {
					printf("]");
				} else {
					printf(")");
				}

				flag = 0;
			}
		}
	}

	if (!have) {
		printf("empty set");
	}
	printf("\n");

	return 0;
}


评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

帅气的东哥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值