标签:
题比较有趣,输入输出比较麻烦。
每个点拆成两个,线段树维护。(这题难点真的在输入输出)
#include<bits/stdc++.h> #define N (1<<17) #define M (l+r>>1) #define P (k<<1) #define S (k<<1|1) #define K l,r,k #define L l,M,P #define R M+1,r,S #define Z int l=0,int r=N,int k=1 int u[N<<2],v[N<<2],a[N<<2]; template<int d> void same(int k){ u[k]=d; v[k]=0; } void flip(int k){ (~u[k]?u[k]:v[k])^=1; } void (*operate[3])(int) ={same<0>,same<1>,flip}; void devolve(int k){ int d=v[k]?2:u[k]; if(~d){ operate[d](P); operate[d](S); v[k]=0; u[k]=-1; } } void A(int d,int s,int t,Z){ if(s==l&&t==r) operate[d](k); else{ devolve(k); if(t<=M) A(d,s,t,L); else if(s>M) A(d,s,t,R); else{ A(d,s,M,L); A(d,M+1,t,R); } } } void finish(Z){ if(~u[k]) for(int i=l;i<=r;++i) a[i]=u[k]; else{ devolve(k); finish(L); finish(R); } } bool empty(){ for(int i=0;i<=N;++i) if(a[i]) return 0; return 1; } int main(){ memset(u,-1,sizeof u); char d[2],b[16]; while(~scanf("%s%s",d,b)){ char u,v; int s,t; sscanf(b,"%c%d,%d%c", &u,&s,&t,&v); s=s*2+(u==‘(‘); t=t*2-(v==‘)‘); if(s>t) continue; if(*d^‘I‘&&*d^‘C‘) A(*d==‘S‘ ?2:*d==‘U‘,s,t); else{ if(*d^‘I‘) A(2,s,t); if(s^0) A(0,0,s-1); if(t^N) A(0,t+1,N); } } finish(); if(empty()) puts("empty set"); else for(int i=0;i<=N;++i){ if((!i||!a[i-1])&&a[i]) printf("%c%d,", i&1?‘(‘:‘[‘,i>>1); if(a[i]&&!a[i+1]) printf("%d%c ", i+1>>1,i&1?‘)‘:‘]‘); } }
bzoj3226: [Sdoi2008]校门外的区间 线段树
标签:
原文地址:http://www.cnblogs.com/f321dd/p/5496069.html