[BZOJ3189][Coci2011][扫描线][线段树]Slika
来源:互联网 发布:淘宝新店卖啥好 编辑:程序博客网 时间:2024/06/16 12:49
首先发现LOAD和与其对应的SAVE之间的操作是没用的,所以可以O(m)扫两遍出去SAVE和LOAD操作。
对于这种矩形覆盖的问题,可以用扫面线加线段树处理。
开两棵线段树,用来记录(x+y)为奇数或偶数的时候被覆盖的情况,我们不妨扫描线扫x坐标,那么随着x+1,只要交换一下两颗线段树就可以了。
对于线段树中的一个结点,开一个set记录一下覆盖了这个结点表示的区间的颜色以及时间,以时间为关键字(我直接记录时间,在外面开个数组记录每个时间对应的颜色),这样就相当于区间覆盖,单点查询。
本地跑得贼慢,交到OJ上跑得比被抓的余畅还快
#include <cstdio>#include <iostream>#include <algorithm>#include <set>#include <vector>#define N 1010#define M 100010using namespace std;int n,m,k,t;int S[M],cl[M];char c[N];struct stp{ int op,x1,y1,x2,y2,c,t;}A[M];vector<stp> b[N],e[N];struct seg{ int l,r; set<int,greater<int> > S;};struct tree{ int L,R,Maxx; seg T[2][N<<3]; tree(){ L=0; R=1; } void Swap(){ swap(L,R); } void insert(int g,int l,int r,int t,int p){ if(T[p][g].l==l&&T[p][g].r==r) return (void)T[p][g].S.insert(t); int mid=T[p][g].l+T[p][g].r>>1; if(r<=mid) insert(g<<1,l,r,t,p); else if(l>mid) insert(g<<1|1,l,r,t,p); else insert(g<<1,l,mid,t,p),insert(g<<1|1,mid+1,r,t,p); } void erase(int g,int l,int r,int x,int p){ if(T[p][g].l==l&&T[p][g].r==r) return (void)T[p][g].S.erase(x); int mid=T[p][g].l+T[p][g].r>>1; if(r<=mid) erase(g<<1,l,r,x,p); else if(l>mid) erase(g<<1|1,l,r,x,p); else erase(g<<1,l,mid,x,p),erase(g<<1|1,mid+1,r,x,p); } void erase(stp x){ if(((x.x2-x.x1+1)&1)^(x.y1&1)) erase(1,x.y1,x.y2,x.t,L); else erase(1,x.y1,x.y2,x.t,R); } void insert(stp x){ if(x.y1&1) insert(1,x.y1,x.y2,x.t,L); else insert(1,x.y1,x.y2,x.t,R); } void query(int g,int x,int p){ if(!T[p][g].S.empty()) Maxx=max(Maxx,*T[p][g].S.begin()); if(T[p][g].l==T[p][g].r) return ; int mid=T[p][g].l+T[p][g].r>>1; if(x<=mid) query(g<<1,x,p); else query(g<<1|1,x,p); } int query(int x){ Maxx=0; query(1,x,(x&1)?L:R); return Maxx; } void Build(int g,int l,int r,int p){ T[p][g].l=l; T[p][g].r=r; T[p][g].S.clear(); if(l==r) return ; int mid=l+r>>1; Build(g<<1,l,mid,p); Build(g<<1|1,mid+1,r,p); } void build(){ Build(1,1,n,0); Build(1,1,n,1); }}T;inline char nc(){ static char buf[100000],*p1=buf,*p2=buf; return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;}inline void rea(int &x){ char c=nc(); x=0; for(;c>'9'||c<'0';c=nc());for(;c>='0'&&c<='9';x=x*10+c-'0',c=nc());}inline void rea(char *x){ char c=nc(); int len=0; for(;c>'Z'||c<'A';c=nc());for(;c>='A'&&c<='Z';x[len++]=c,c=nc());}int main(){ rea(n); rea(k); rea(m); cl[0]=1; for(int i=1;i<=m;i++){ rea(c); A[i].t=i; if(c[0]=='S') A[i].op=1; else if(c[0]=='L') A[i].op=2,rea(A[i].c); else{ rea(A[i].c),rea(A[i].x1),rea(A[i].y1),rea(A[i].x2),rea(A[i].y2); A[i].x1++; A[i].x2++; A[i].y1++; A[i].y2++; cl[i]=A[i].c; } } for(int i=1;i<=m;i++) if(A[i].op==1) S[++t]=i; /*for(int i=m;i>0;i--){ if(A[i].op==0) printf("%d %d\n",A[i].x1,A[i].x2); else if(A[i].op==2) i=S[A[i].c]; } return 0;*/ for(int i=m;i>0;i--){ if(A[i].op==0){ b[A[i].x1].push_back(A[i]); e[A[i].x2+1].push_back(A[i]); } else if(A[i].op==2) i=S[A[i].c]; } T.build(); for(int i=1;i<=n;i++,putchar('\n')){ T.Swap(); for(int j=0;j<e[i].size();j++) T.erase(e[i][j]); for(int j=0;j<b[i].size();j++) T.insert(b[i][j]); for(int j=1;j<=n;j++) printf("%d ",cl[T.query(j)]); } return 0;}
0 0
- [BZOJ3189][Coci2011][扫描线][线段树]Slika
- 线段树[扫描线]
- 线段树+扫描线
- 线段树 扫描线
- 线段树扫描线
- 线段树-扫描线
- hdu4007 线段树扫描线
- poj2482 线段树扫描线
- poj2464 线段树扫描线
- ural1707 线段树扫描线
- hdu4419 线段树扫描线
- hdu1828线段树+扫描线
- POJ1177+线段树+扫描线
- POJ1151+线段树+扫描线
- HDU3255(线段树+扫描线)
- 线段树扫描线upcoj2540
- 线段树之扫描线
- 线段树扫描线hdu4052
- 翻转链表
- hdu 1022 简单的栈应用
- Tomcat 安装以及部署网站实例
- ARM SMMUv3 architecture in linux
- 单例模式
- [BZOJ3189][Coci2011][扫描线][线段树]Slika
- 引用
- YOLO V2教程之训练自己的数据
- Jquery怎么获取select选中项 自定义属性的值
- SpringMVC3的ResponseBody返回字符串乱码问题解决
- Win10下Python的安装及相关库的安装
- python——爬虫学习——Beautiful Soup库的使用-(2)
- 文章标题
- 外挂学习之路(13)--- 地图资源的提取