[線分樹マーク]BZOJ 3226[Sdoi 2008]学外の区間
3619 ワード
マークを入れて、二つのマークが死んでしまいました.
まだl>r狂Tを判定していませんので.
線分樹を復習しても、簡単というデータ構造は、多くのことを体得することができます.
まだl>r狂Tを判定していませんので.
線分樹を復習しても、簡単というデータ構造は、多くのことを体得することができます.
#include<cstdio>
#include<cstdlib>
#include<algorithm>
using namespace std;
inline 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;
}
struct Seg{
int M,TH;
int H[600005],R[600005];
inline void Build(int n){
for (M=1;M<n+2;M<<=1,TH++);
for (int i=1;i<M;i++)
H[i]=-1;
}
inline void pushdown(int x){
if (R[x])
{
R[x<<1]^=1; if (H[x<<1]!=-1) H[x<<1]^=1;
R[x<<1|1]^=1; if (H[x<<1|1]!=-1) H[x<<1|1]^=1;
R[x]^=1;
}
if (H[x]!=-1)
{
H[x<<1]=H[x<<1|1]=H[x];
H[x]=-1;
}
}
inline void Pushdown(int rt){
int p;
for (int i=TH;i;i--)
pushdown(rt>>i);
}
inline void Reverse(int s,int t){
if (s>t) return;
for (Pushdown(s+=M-1),Pushdown(t+=M+1);s^t^1;s>>=1,t>>=1)
{
if (~s&1) { R[s^1]^=1; if (H[s^1]!=-1) H[s^1]^=1; }
if ( t&1) { R[t^1]^=1; if (H[t^1]!=-1) H[t^1]^=1; }
}
}
inline void Change(int s,int t,int c){
if (s>t) return;
for (Pushdown(s+=M-1),Pushdown(t+=M+1);s^t^1;s>>=1,t>>=1)
{
if (~s&1) H[s^1]=c,R[s^1]=0;
if ( t&1) H[t^1]=c,R[t^1]=0;
}
}
inline int Query(int s){
Pushdown(s+=M);
return H[s];
}
}SEG;
const int n=(65536*2+1);
//const int n=(5*2+1);
int main()
{
int a,b;
char ch[3];
char type, flag_l, flag_r,flag=0;
freopen("t.in","r",stdin);
freopen("t.out","w",stdout);
SEG.Build(n);
while (~scanf("%s",ch))
{
a=read(); b=read();
a+=2; b+=2;
switch(ch[0])
{
case 'U':
SEG.Change(a,b,1);
// for(int i=1;i<=n;i++) printf("%d ",SEG.Query(i)); printf("
");
break;
case 'I':
SEG.Change(1,a-1,0);
// for(int i=1;i<=n;i++) printf("%d ",SEG.Query(i)); printf("
");
SEG.Change(b+1,n,0);
// for(int i=1;i<=n;i++) printf("%d ",SEG.Query(i)); printf("
");
break;
case 'D':
SEG.Change(a,b,0);
// for(int i=1;i<=n;i++) printf("%d ",SEG.Query(i)); printf("
");
break;
case 'C':
SEG.Change(1,a-1,0);
// for(int i=1;i<=n;i++) printf("%d ",SEG.Query(i)); printf("
");
SEG.Change(b+1,n,0);
// for(int i=1;i<=n;i++) printf("%d ",SEG.Query(i)); printf("
");
SEG.Reverse(a,b);
// for(int i=1;i<=n;i++) printf("%d ",SEG.Query(i)); printf("
");
break;
case 'S':
SEG.Reverse(a,b);
// for(int i=1;i<=n;i++) printf("%d ",SEG.Query(i)); printf("
");
break;
}
}
int start=-1,last=-1;
flag=0;
// for(int i=1;i<=n;i++) printf("%d ",SEG.Query(i)); printf("
");
for(int i=1;i<=n;i++)
if(SEG.Query(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)
printf("empty set
");
return 0;
}