列表

详情


NC20314. [SDOI2008]校门外的区间

描述

受校门外的树这道经典问题的启发,A君根据基本的离散数学的知识,抽象出5种运算维护集合S(S初始为空)并最终输出S。现在,请你完成这道校门外的树之难度增强版——校门外的区间。   
5种运算如下:                    
U T
S∪T
I T
S∩T
D T
S-T
C T T-S
S T
S⊕T
基本集合运算如下:     
A∪B
{x : xÎA or xÎB}
A∩B
{x : xÎA and xÎB}
A-B
{x : xÎA and xÏB}
A⊕B
(A-B)∪(B-A)  


输入描述

输入共M行。
每行的格式为X T,用一个空格隔开,X表示运算的种类,T为一个区间(区间用(a,b), (a,b], [a,b), [a,b]表示)。

输出描述

共一行,即集合S,每个区间后面带一个空格。若S为空则输出"empty set"。

示例1

输入:

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

输出:

(2,3)

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++(g++ 7.5.0) 解法, 执行用时: 65ms, 内存消耗: 7384K, 提交时间: 2023-07-09 22:59:37

#include<bits/stdc++.h>
using namespace std;
const int N=2e5;
const int M=1e7;
const int mod=998244353;
const int INF=0x3f3f3f3f;
struct Tree{
	int val,lazy1,lazy2;
	//lazy1 赋值 lazy2 翻转
}tree[(N+5)<<2];
string opt,inv;
void build(int x,int l,int r){
	tree[x].lazy1=-1;
	if(l==r)return;
	int mid=(l+r)/2;
	build(x<<1,l,mid);
	build(x<<1|1,mid+1,r);
}
void pushup(int x){
	tree[x].val=(tree[x<<1].val+tree[x<<1|1].val);
}
void pushdown(int x,int l,int r){
	int mid=(l+r)/2;
	if(tree[x].lazy1!=-1){
		tree[x<<1].lazy1=tree[x].lazy1;
		tree[x<<1].lazy2=0;
		tree[x<<1|1].lazy1=tree[x].lazy1;
		tree[x<<1|1].lazy2=0;
		tree[x<<1].val=tree[x].lazy1*(mid-l+1);
		tree[x<<1|1].val=tree[x].lazy1*(r-mid);
		tree[x].lazy1=-1;
	}
	if(tree[x].lazy2){
		tree[x<<1].val=(mid-l+1)-tree[x<<1].val;
		tree[x<<1|1].val=(r-mid)-tree[x<<1|1].val;
		tree[x<<1].lazy2=!tree[x<<1].lazy2;
		tree[x<<1|1].lazy2=!tree[x<<1|1].lazy2;
		tree[x].lazy2=0;
	}
}
void update_cov(int x,int l,int r,int L,int R,int val){
	if(L>R)return;
	if(L<=l && r<=R){
		tree[x].val=val*(r-l+1);
		tree[x].lazy1=val;
		tree[x].lazy2=0;
		return;
	}
	pushdown(x,l,r);
	int mid=(l+r)/2;
	if(L<=mid)update_cov(x<<1,l,mid,L,R,val);
	if(R>mid)update_cov(x<<1|1,mid+1,r,L,R,val);
	pushup(x);
}
void update_flip(int x,int l,int r,int L,int R){
	if(L>R)return;
	if(L<=l && r<=R){
		tree[x].val=r-l+1-tree[x].val;
		tree[x].lazy2=!tree[x].lazy2;
		return;
	}
	pushdown(x,l,r);
	int mid=(l+r)/2;
	if(L<=mid)update_flip(x<<1,l,mid,L,R);
	if(R>mid)update_flip(x<<1|1,mid+1,r,L,R);
	pushup(x);
}
int ans[N+5];
void query(int x,int l,int r){
	if(l==r){
		ans[l]=tree[x].val;
		return;
	}
	pushdown(x,l,r);
	int mid=(l+r)/2;
	query(x<<1,l,mid);
	query(x<<1|1,mid+1,r);
}
int main(){
	ios::sync_with_stdio(0);
	cin.tie(0),cout.tie(0);
	build(1,1,N);
	while(cin>>opt){
		cin>>inv;
		int l=0,r=0,len=(int)inv.size();
		for(int i=1;i<len;i++){
			if(inv[i]==','){
				for(int j=i+1;j<len-1;j++)
					r=r*10+(inv[j]-'0');
				break;
			}
			else l=l*10+(inv[i]-'0');
		}
		if(inv[0]=='(')l=l*2+2;
		else l=l*2+1;
		if(inv[len-1]==')')r=r*2;
		else r=r*2+1;
		if(l>r)continue;
		if(opt[0]=='U')update_cov(1,1,N,l,r,1);
		else if(opt[0]=='I'){
			update_cov(1,1,N,1,l-1,0);
			update_cov(1,1,N,r+1,N,0);
		}
		else if(opt[0]=='D')update_cov(1,1,N,l,r,0);
		else if(opt[0]=='S')update_flip(1,1,N,l,r);
		else{
			update_flip(1,1,N,1,N);
			update_cov(1,1,N,1,l-1,0);
			update_cov(1,1,N,r+1,N,0);
		}
	}
	query(1,1,N);
	if(tree[1].val==0){
		cout<<"empty set";
		return 0;
	}
	int f=0;
	for(int i=1;i<=N;i++){
		if(ans[i] && f==0){
			f=1;
			if(i&1)cout<<'[';
			else cout<<'(';
			cout<<(i-1)/2<<',';
		}
		if(ans[i+1]==0 && f){
			f=0;
			cout<<i/2;
			if(i&1)cout<<']';
			else cout<<')';
			cout<<" ";
		}
	}
	return 0;
}

C++11(clang++ 3.9) 解法, 执行用时: 72ms, 内存消耗: 5732K, 提交时间: 2019-03-16 11:50:10

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#include<queue>
#define ll long long
#define inf 1000000000
#define n (65536*2+1)
using namespace std;
int read()
{
    int x=0,f=0;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='(')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	if(ch==')')f=1;
    return x*2-f;
}
char ch[5];
struct seg{int l,r,val,tag,rev;}t[4*n];
void build(int k,int l,int r)
{
	t[k].l=l;t[k].r=r;t[k].tag=-1;
	if(l==r)return;
	int mid=(l+r)>>1;
	build(k<<1,l,mid);
	build(k<<1|1,mid+1,r);
}
void pushdown(int k)
{
	int tag=t[k].tag,rev=t[k].rev;
	t[k].tag=-1;t[k].rev=0;
	if(t[k].l==t[k].r)
	{
		if(tag!=-1)
			t[k].val=tag;
		t[k].val^=rev;;
		return;
	}
	if(tag!=-1)
	{
		t[k<<1].tag=t[k<<1|1].tag=tag;
		t[k<<1].rev=t[k<<1|1].rev=0;
	}
	t[k<<1].rev^=rev;t[k<<1|1].rev^=rev;
}
int query(int k,int x)
{
	pushdown(k);
	int l=t[k].l,r=t[k].r;
	if(l==r)return t[k].val;
	int mid=(l+r)>>1;
	if(x<=mid)return query(k<<1,x);
	else return query(k<<1|1,x);
}
void modify(int k,int x,int y,int val)
{
	if(y<x)return;
	pushdown(k);
	int l=t[k].l,r=t[k].r;
	if(l==x&&y==r)
	{
		if(val==-1)t[k].rev^=1;
		else t[k].tag=val;
		return;
	}
	int mid=(l+r)>>1;
	if(y<=mid)modify(k<<1,x,y,val);
	else if(x>mid)modify(k<<1|1,x,y,val);
	else 
	{
		modify(k<<1,x,mid,val);
		modify(k<<1|1,mid+1,y,val);
	}
}
void rever(int k,int x,int y)
{
    modify(k,x,y,-1);
}
int main()
{
	build(1,1,n);
	while(scanf("%s",ch)!=EOF)
	{
		int a=read(),b=read();
		a+=2;b+=2;
		switch(ch[0])
		{
		case 'U':modify(1,a,b,1);break;
		case 'I':modify(1,1,a-1,0);modify(1,b+1,n,0);break;
		case 'D':modify(1,a,b,0);break;
		case 'C':modify(1,1,a-1,0);modify(1,b+1,n,0);rever(1,a,b);break;
		case 'S':rever(1,a,b);break;
		}
	}
	int start=-1,last=-1,flag=0;
	for(int i=1;i<=n;i++)
		if(query(1,i))
		{
			if(start==-1)start=i;
			last=i;
		}
		else 
		{
			if(start!=-1)
			{
				if(flag)printf(" ");
				else flag=1;
				if(start&1)printf("(");
				else printf("[");
				printf("%d",start/2-1);
				printf(",");
				printf("%d",(last+1)/2-1);
				if(last&1)printf(")");
				else printf("]");
			}
			last=start=-1;
		}
	if(!flag)puts("empty set");
	return 0;
}

上一题