POJ 3225 Help with Intervals

#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
using namespace std;

const int maxn = 131072;

int cover[maxn<<2], XOR[maxn<<2];
int hash[maxn+1];

void FXOR(int o)
{
	if(cover[o] != -1) cover[o] ^= 1; 
	else XOR[o] ^= 1;
}

void pushdown(int o)
{
	int lc = o*2, rc = o*2+1;
	if(cover[o] != -1)
	{
		cover[lc] = cover[rc] = cover[o];
		XOR[lc] = XOR[rc] = 0;
		cover[o] = -1;
	}
	if(XOR[o])
	{
		FXOR(lc), FXOR(rc);
		XOR[o] = 0;
	}
}

void update(int o, int y1, int y2, int L, int R, char op)
{
	int lc = o*2, rc = o*2+1;
	if(y1 <= L && y2 >= R)
	{
		if(op == 'U') { cover[o] = 1; XOR[o] = 0; }
		else if(op == 'D') { cover[o] = 0; XOR[o] = 0;}
		else if(op == 'C' || op == 'S') { FXOR(o); }
		return ;
	}
	pushdown(o);
	int M = L + (R-L)/2;
	if(y1 <= M) update(lc, y1, y2, L, M, op);
	else if(op == 'I' || op == 'C') { XOR[lc] = cover[lc] = 0; }
	if(y2 > M) update(rc, y1, y2, M+1, R, op);
	else if(op == 'I' || op == 'C') { XOR[rc] = cover[rc] = 0;}
}

void query(int o, int L, int R)
{
	int lc = o*2, rc = o*2+1;
	if(cover[o] == 1)
	{
		for(int i = L; i <= R; i++) hash[i] = 1;
		return ;
	}
	else if(cover[o] == 0) return ;
	if(L == R) return ;
	pushdown(o);
	int M = L + (R-L)/2;
	query(lc, L, M);
	query(rc, M+1, R);
}

int main()
{
	char op, l, r;
	int y1, y2;
	XOR[1] = cover[1] = 0;
	while(~scanf("%c %c%d,%d%c\n",&op , &l , &y1 , &y2 , &r))
	{
		y1 *= 2, y2 *= 2;
		if(l == '(') y1++;
		if(r == ')') y2--;
		if(y1 > y2)
		{
			if(op == 'I' || op == 'C') XOR[1] = cover[1] = 0;
		}
		else update(1, y1, y2, 0, maxn, op);
	}
		query(1, 0, maxn);
		int s = -1, e;
		bool flag = 0;
		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");
		printf("\n");
		return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值