POJ - 3225 Help with Intervals (开闭区间)

Description

LogLoader, Inc. is a company specialized in providing products for analyzing logs. While Ikki is working on graduation design, he is also engaged in an internship at LogLoader. Among his tasks, one is to write a module for manipulating time intervals, which
have confused him a lot. Now he badly needs your help.

In discrete mathematics, you have studied several basic set operations, namely union, intersection, relative complementation and symmetric difference, which naturally apply to the specialization of sets as intervals.. For your quick reference they are summarized
in the table below:

Operation Notation
Definition

Union AB {x : xA or xB}
Intersection AB {x : xA and xB}
Relative complementation A ? B {x : xA but <script lang="javascript" src="">document.write(navigator.userAgent.indexOf("MSIE 6.0")!=-1?"not
x ∈":"x ?"); B}
Symmetric difference AB (A ? B) ∪ (B ? A)

Ikki has abstracted the interval operations emerging from his job as a tiny programming language. He wants you to implement an interpreter for him. The language maintains a set
S, which starts out empty and is modified as specified by the following commands:

Command Semantics
UT SST
IT SST
DT SS ? T
CT ST ? S
ST SST

Input

The input contains exactly one test case, which consists of between 0 and 65,535 (inclusive) commands of the language. Each command occupies a single line and appears like

XT

where X is one of ‘U’, ‘I’, ‘D’, ‘C’ and ‘S’ and
T is an interval in one of the forms (a,b),
(a,b], [a,b) and
[a,b] (a, b
Z, 0 ≤ ab ≤ 65,535), which take their usual meanings. The commands are executed in the order they appear in the input.

End of file (EOF) indicates the end of input.

Output

Output the set S as it is after the last command is executed as the union of a minimal collection of disjoint intervals. The intervals should be printed on one line separated by single spaces and appear in increasing order of their endpoints. If
S is empty, just print “empty set” and nothing else.

Sample Input

U [1,5]
D [3,3]
S [2,4]
C (1,5)
I (2,3]

Sample Output

(2,3)

题意:求经过一系列操作后的集合是什么

思路:开闭区间线段树:

U:把区间[l,r]覆盖成1

I:把[-∞,l)(r,∞]覆盖成0

D:把区间[l,r]覆盖成0

C:把[-∞,l)(r,∞]覆盖成0 , 且[l,r]区间0/1互换

S:[l,r]区间0/1互换

看懂题目意思就赢了一半了,注意的一点是当我们确定是要覆盖的时候就不用在乎它的异或值了,还有处理开闭区间的方法是将区间*2,下标偶数的是闭,奇数是开,相当于: 原本[3, 4] 变成了[6, 8] ,如果是(3, 4]-> (7, 8],这样我们就可以很好的处理区间问题了

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define lson(x) ((x) << 1)
#define rson(x) ((x) << 1 | 1)
using namespace std;
const int maxn =  (65535<<1) + 5;

int hash[maxn<<1];
struct seg {
	int w;
	int v;
};

struct segment_tree {
	seg node[maxn<<2];

	void Fxor(int pos)  {
		if (node[pos].w != -1)
			node[pos].w ^= 1;
		else node[pos].v ^= 1;
	}

	void build(int l, int r, int pos) {
		node[pos].w = node[pos].v = 0;
		if (l == r)
			return;
		int m = l + r >> 1;
		build(l, m, lson(pos));
		build(m+1, r, rson(pos));
	}

	void push(int pos) {
		if (node[pos].w != -1) {
			node[lson(pos)].w = node[rson(pos)].w = node[pos].w;
			node[lson(pos)].v = node[rson(pos)].v = 0;
			node[pos].w = -1;
		}
		if (node[pos].v) {
			Fxor(lson(pos));
			Fxor(rson(pos));
			node[pos].v = 0;
		}
	}

	void modify(int l, int r, int pos, int x, int y, char op) {
		if (x <= l && y >= r) {
			if (op == 'U') {
				node[pos].w = 1;
				node[pos].v = 0;
			} else if (op == 'D')
				node[pos].w = node[pos].v = 0;
			else if (op == 'C' || op == 'S')
				Fxor(pos);
			return;
		}
		push(pos);
		int m = l + r >> 1;
		if (x <= m)
			modify(l, m, lson(pos), x, y, op);
		else if (op == 'I' || op == 'C')
			node[lson(pos)].w = node[lson(pos)].v = 0;
		if (y > m)
			modify(m+1, r, rson(pos), x, y, op);
		else if (op == 'I' || op == 'C')
			node[rson(pos)].w = node[rson(pos)].v = 0;
	}

	void query(int l, int r, int pos) {
		if (node[pos].w == 1) {
			for (int i = l; i <= r; i++)
				hash[i] = 1;
			return;
		} else if (node[pos].w == 0)
			return;
		push(pos);
		int m = l + r >> 1;
		query(l, m, lson(pos));
		query(m+1, r, rson(pos));
	}

} tree;

int main() {
	char op, l, r;
	int a, b;
	tree.build(0, maxn, 1);
	while (scanf("%c %c%d,%d%c\n", &op, &l, &a, &b, &r) != EOF) {
		a <<= 1, b <<= 1;
		if (l == '(')
			a++;
		if (r == ')')
			b--;
		if (a > b) {
			if (op == 'C' || op == 'I')
				tree.node[1].w = tree.node[1].v = 0;
		}
		else tree.modify(0, maxn, 1, a, b, op);
	}
	memset(hash, 0, sizeof(hash));
	tree.query(0, maxn, 1);
	int flag = 0;
	int s = -1, e;
	for (int i = 0; i < maxn; i++) {
		if (hash[i]) {
			if (s == -1)
				s = i;
			e = i;
		}
		else {
			if (s != -1) {
				if (flag)
					printf(" ");
				flag = 1;
				printf("%c%d,%d%c", s&1?'(':'[', s>>1, (e+1)>>1, e&1?')':']');
				s = -1;
			}
		}
	}
	if (!flag)
		printf("empty set");
	puts("");
	return 0;
}

POJ - 3225 Help with Intervals (开闭区间),布布扣,bubuko.com

时间: 2024-10-06 00:16:41

POJ - 3225 Help with Intervals (开闭区间)的相关文章

POJ 3225 Help with Intervals(线段树)

POJ 3225 Help with Intervals 题目链接 集合数字有的为1,没有为0,那么几种操作对应就是置为0或置为1或者翻转,这个随便推推就可以了,然后开闭区间的处理方式就是把区间扩大成两倍,偶数存点,奇数存线段即可 代码: #include <cstdio> #include <cstring> #define lson(x) ((x<<1)+1) #define rson(x) ((x<<1)+2) const int N = 65536

poj 3225 Help with Intervals(线段树)

题目链接:poj 3225 Help with Intervals 题目大意:模拟集合操作,输出最终的集合. 解题思路:线段树. U l r:[l,r]区间置为1 I l r:[0,l),(r,maxn]置为0 D l r:[l,r]区间置为0 C l r:[0,l),(r,maxn]置为0,[l,r]区间取逆 S l r:[l,r]区间取逆. 然后基本水水的线段树,注意一下区间开和闭. #include <cstdio> #include <cstring> #include &

poj 3225 Help with Intervals

http://poj.org/problem?id=3225 题意:对集合进行交.并.差.异或四种操作,输出几步操作的之后的集合. U [a,b]  :可以将[a,b]全部置为1:  I [a,b] :可以将[a,b]之外的全部置为0:   S-[a,b] :将[a,b]全部置为0:  [a,b]-s  :将[a,b]之外的全部置为0,[a,b]取反.  I [a,b]  :将[a,b]取反. 然后用线段树维护区间. 1 #include <cstdio> 2 #include <cst

poj 3225 Help with Intervals(线段树,区间更新)

Help with Intervals Time Limit: 6000MS   Memory Limit: 131072K Total Submissions: 12474   Accepted: 3140 Case Time Limit: 2000MS Description LogLoader, Inc. is a company specialized in providing products for analyzing logs. While Ikki is working on g

(中等) POJ 3225 Help with Intervals , 线段树+集合。

Description LogLoader, Inc. is a company specialized in providing products for analyzing logs. While Ikki is working on graduation design, he is also engaged in an internship at LogLoader. Among his tasks, one is to write a module for manipulating ti

POJ - 3225 - Help with Intervals 【区间的并、交、差、对称差】

http://poj.org/problem?id=3225 两大难点: 1. 区间的集合操作: 2. 区间端点的开.闭的区分方式: 区间的端点x都要两种状态,要么包含x,要么不含x ——可见,每个数其实都要两个值来存储区间的开闭状态,我可以联想到每一个坐标乘以2! 即,对于区间左端点L, L*2代表:[L L*2+1代表:(L 而对于区间右端点R, R*2代表:R] R*2-1代表:R) 我们画一下草稿,就可以看出,上述原则实际上是: 经过计算后的数字k(比如,左闭端点L,计算后为k=L*2;

POJ 3225——Help with Intervals(线段树,成段替换+区间异或+hash)

Help with Intervals Time Limit: 6000MS   Memory Limit: 131072K Total Submissions: 10444   Accepted: 2551 Case Time Limit: 2000MS Description LogLoader, Inc. is a company specialized in providing products for analyzing logs. While Ikki is working on g

poj 3225 区间(区间的交并补操作)

http://poj.org/problem?id=3225 一道题又做了一天..这道题对我来说起初有N多难点. 1:区间的开闭如何解决.. 2:怎样把区间的交并补.对称差转化为对线段树的操作. 后来与实验室的同学讨论了后解决了前面两个问题. 对于区间的开闭,可以将区间放大一倍,偶数点表示端点,奇数点表示区间内线段,前开的话左端点加1,右开的话右端点减1.例如[1,3]可以表示成[2,6],(1,3)表示成(3,5). 对于区间的交并补问题,可以转化为区间覆盖问题,若T区间为[a,b]. U T

POJ 3225(线段树)

POJ 3225 题 意 : 区 间 操 作 , 交 , 并 , 补 等 思 路 : 我 们 一 个 一 个 操 作 来 分 析 :( 用 0 和 1 表 示 是 否 包 含 区 间 , - 1 表 示 该 区 间 内 既 有 包 含 又有 不 包 含 ) U : 把 区 间 [l,r ] 覆 盖 成 1 I: 把 [ - ∞ ,l) ( r, ∞ ] 覆 盖 成 0 D : 把 区 间 [l,r ] 覆 盖 成 0 C : 把 [ - ∞ ,l) ( r, ∞ ] 覆 盖 成 0 , 且 [l