【分块】bzoj3226 [Sdoi2008]校门外的区间
2014-11-27 12:15
387 查看
题解见 : http://blog.csdn.net/iamzky/article/details/41088151
ORZ ZKY
2个懒标记:是否翻转,覆盖成了什么。
怎么处理一个块上有两个标记的情况呢?
若该块原来没有任何标记,或要打的标记和原本的标记种类相同,则直接打上标记;
若已有翻转标记,再覆盖时则先清除翻转标记,再打上覆盖标记;
若已有覆盖标记,再翻转时,则直接将覆盖标记取反。
So 某个块上同时只会有1个标记。
P.S.分块此题挺快的……
ORZ ZKY
2个懒标记:是否翻转,覆盖成了什么。
怎么处理一个块上有两个标记的情况呢?
若该块原来没有任何标记,或要打的标记和原本的标记种类相同,则直接打上标记;
若已有翻转标记,再覆盖时则先清除翻转标记,再打上覆盖标记;
若已有覆盖标记,再翻转时,则直接将覆盖标记取反。
So 某个块上同时只会有1个标记。
P.S.分块此题挺快的……
#include<cstdio> #include<cstring> using namespace std; #define sz 370 const int n=131070; char op[1],cl,cr; int x,y,num[132000],l[sz],r[sz],cov[sz],sum; bool a[132000],spin[sz],goal; void makeblock() { for(sum=1;sum*sz<n;++sum) { l[sum]=r[sum-1]+1; r[sum]=sum*sz; for(int i=l[sum];i<=r[sum];++i) num[i]=sum; } l[sum]=r[sum-1]+1; r[sum]=n; for(int i=l[sum];i<=r[sum];++i) num[i]=sum; memset(cov,-1,sizeof(cov)); } void pushdown(const int &p) { if(cov[p]!=-1) { for(int i=l[p];i<=r[p];i++) a[i]=cov[p]; cov[p]=-1; } else if(spin[p]) { for(int i=l[p];i<=r[p];i++) a[i]^=1; spin[p]=0; } } void update(const int &L,const int &R,const bool &sym) { pushdown(num[L]); pushdown(num[R]); if(num[L]==num[R]) {for(int i=L;i<=R;++i) a[i]=sym;} else { for(int i=L;i<=r[num[L]];++i) a[i]=sym; for(int i=l[num[R]];i<=R;++i) a[i]=sym; for(int i=num[L]+1;i<num[R];++i) {spin[i]=0; cov[i]=sym;} } } void rotate(const int &L,const int &R) { pushdown(num[L]); pushdown(num[R]); if(num[L]==num[R]) {for(int i=L;i<=R;++i) a[i]^=1;} else { for(int i=L;i<=r[num[L]];++i) a[i]^=1; for(int i=l[num[R]];i<=R;++i) a[i]^=1; for(int i=num[L]+1;i<num[R];++i) if(cov[i]==-1) spin[i]^=1; else cov[i]^=1; } } int Ma(const int &v,const char &c) { if(c=='['||c==']') return (v<<1); else if(c=='(') return (v<<1)+1; else return (v<<1)-1; } int main() { makeblock(); while(scanf("%s %c%d,%d%c",op,&cl,&x,&y,&cr)!=EOF) { if(op[0]=='U') update(Ma(x,cl),Ma(y,cr),1); else if(op[0]=='I') { if(x) update(0,Ma(x,cl)-1,0); if(y!=65535) update(Ma(y,cr)+1,65535<<1,0); } else if(op[0]=='D') update(Ma(x,cl),Ma(y,cr),0); else if(op[0]=='C') { rotate(Ma(x,cl),Ma(y,cr)); if(x) update(0,Ma(x,cl)-1,0); if(y!=65535) update(Ma(y,cr)+1,65535<<1,0); } else rotate(Ma(x,cl),Ma(y,cr)); } int head=0; for(int i=1;i<=sum;++i) pushdown(i); for(int i=0;i<=n;++i) { if(((!i) && a[i]) || (a[i] && (!a[i-1]))) head=i; if((i==n && a[i]) || (a[i] && (!a[i+1]))) { goal=1; if(head&1) putchar('('); else putchar('['); printf("%d,",head>>1); if(i&1) {printf("%d",i+1>>1); putchar(')');} else {printf("%d",i>>1); putchar(']');} putchar(' '); } } if(!goal) puts("empty set"); return 0; }
相关文章推荐
- BZOJ 3226: [Sdoi2008]校门外的区间
- [bzoj3226][Sdoi2008]校门外的区间——线段树
- bzoj 3226 [Sdoi2008]校门外的区间(线段树)
- BZOJ-3226 [SDOI2008]校门外的区间
- 【bzoj3226】[Sdoi2008]校门外的区间
- [线段树 标记] BZOJ 3226 [Sdoi2008]校门外的区间
- [BZOJ]3226: [Sdoi2008]校门外的区间 线段树
- BZOJ 题目 3226: [Sdoi2008]校门外的区间(线段树区间交并差异或)
- bzoj 3226: [Sdoi2008]校门外的区间(线段树)
- 【SDOI2008】【BZOJ3226】校门外的区间
- bzoj3226: [Sdoi2008]校门外的区间 线段树
- [BZOJ3226][SDOI2008]校门外的区间(线段树)
- bzoj 3226: [Sdoi2008]校门外的区间
- BZOJ 3226 [SDOI2008]校门外的区间
- 3226: [Sdoi2008]校门外的区间
- 3226: [Sdoi2008]校门外的区间
- 3226: [Sdoi2008]校门外的区间 线段树
- 3226: [Sdoi2008]校门外的区间
- 【BZOJ】【P3226】【Sdoi2008】【校门外的区间】【题解】【线段树】
- 【BZOJ3226】【codevs2297】校门外的区间,线段树