BZOJ-3226 [SDOI2008]校门外的区间

线段树即可。。。

区间各种混乱。。。开闭区间的话,可以在每两个数x,y中插入两个数,左边那个无限接近大于x,右边那个无限接近小于x。

U操作:将[x,y]修改为True

I操作:将除了[x,y]以外修改为False

D操作:将[x,y]修改为False

S操作:将[x,y]真假反转

C操作:I操作+S操作

#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <cctype>
#include <cmath>
#include <algorithm>
#include <iostream>
#define rep(i, l, r) for(int i=l; i<=r; i++)
#define clr(x, c) memset(x, c, sizeof(x))
#define lowbit(x) (x&-x)
#define maxn 1572864
#define maxl 196605
#define l(x) x*2
#define r(x) x*2+1
using namespace std;
inline int read1()
{
	int x=0, f=0; char ch=getchar();
	while (!isdigit(ch)) {if (ch=='(') f=1; ch=getchar();}
	while (isdigit(ch)) x=x*10+ch-'0', ch=getchar();
	return x*3+f;
}
inline int read2()
{
	int x=0, f=0; char ch=getchar();
	while (!isdigit(ch)) ch=getchar();
	while (isdigit(ch)) x=x*10+ch-'0', ch=getchar();
	if (ch==')') f=-1;
	return x*3+f;
}
int L, R, E, s[maxn];
bool rev[maxn], tag[maxn], k[maxn];

inline void pushdown(int l, int r, int t)
{
	int mid=(l+r)>>1;
	if (rev[t])
	{
		rev[l(t)]^=1, rev[r(t)]^=1, rev[t]^=1;
		s[l(t)]=mid-l+1-s[l(t)], s[r(t)]=r-mid-s[r(t)];
	}
	if (tag[t]) 
	{
		tag[l(t)]=tag[r(t)]=1; tag[t]=0;
		if (s[t]) s[l(t)]=mid-l+1, s[r(t)]=r-mid; else s[l(t)]=s[r(t)]=0;
	}
}
void Edit(int l, int r, int t)
{
	if (L>R) return;
	if (rev[t] || tag[t]) pushdown(l, r, t);
	if (L<=l && r<=R) {tag[t]=1, s[t]=E?r-l+1:0; return;}
	int mid=(l+r)>>1;
	if (L<=mid) Edit(l, mid, l(t));
	if (mid<R) Edit(mid+1, r, r(t));
	s[t]=s[l(t)]+s[r(t)];
}
void Rev(int l, int r, int t)
{
	if (L>R) return;
	if (rev[t] || tag[t]) pushdown(l, r, t);
	if (L<=l && r<=R) {rev[t]=1, s[t]=r-l+1-s[t]; return;}
	int mid=(l+r)>>1;
	if (L<=mid) Rev(l, mid, l(t));
	if (mid<R) Rev(mid+1, r, r(t));
	s[t]=s[l(t)]+s[r(t)];
}
void dfs(int l, int r, int t)
{
	if (l==r) {k[l]=s[t]; return;}
	if (rev[t] || tag[t]) pushdown(l, r, t);
	int mid=(l+r)>>1; dfs(l, mid, l(t)); dfs(mid+1, r, r(t));
}
int main()
{
	char c[5];
	while (~scanf("%s", c))
	{
		int x=read1(), y=read2();
		if (c[0]=='U') E=1, L=x, R=y, Edit(0, maxl, 1);
		else if (c[0]=='I') E=0, L=0, R=x-1, Edit(0, maxl, 1), L=y+1, R=maxl, Edit(0, maxl, 1);
		else if (c[0]=='D') E=0, L=x, R=y, Edit(0, maxl, 1);
		else if (c[0]=='S') L=x, R=y, Rev(0, maxl, 1);
		else E=0, L=0, R=x-1, Edit(0, maxl, 1), L=y+1, R=maxl, Edit(0, maxl, 1), L=x, R=y, Rev(0, maxl, 1);
	}
	if (!s[1]) {printf("empty set\n"); return 0;}
	dfs(0, maxl, 1);
	bool flag=0; int now=0; while (now<=maxl)
	{
		while (!k[now] && now<=maxl) now++;
		if (now>maxl) break;
		if (flag) printf(" "); else flag=1;
		printf("%c%d,", now%3==1?'(':'[', now/3);
		while (k[now] && now<=maxl) now++;
		printf("%d%c", now/3, now%3==1?']':')');
	}
	return 0;
}
posted @ 2015-05-05 18:00  NanoApe  阅读(182)  评论(0编辑  收藏  举报
AmazingCounters.com