做法:这题比ural那题简单,因为是球,所以离散化时记录区间边间点和中间的两个点就好了。
//列SUM组的方法也只适用于,空出的的格子可以不用考虑的情况啊 #include<cstdio> #include<cstring> #include<algorithm> #define left l,m,x<<1 #define right m+1,r,x<<1|1 using namespace std; const int LMT=12005; const int eps=1<<31-1; int cov[LMT<<2],myx[LMT],leng,cnt; bool seg[LMT]; struct line { int a,b; char c; }e[LMT]; inline int max(int a,int b) { return a>b?a:b; } void init(void) { cov[1]=1; memset(seg,1,sizeof(seg)); cnt=0;leng=0; } void cut(int x) { if(cov[x]!=-1) { cov[x<<1]=cov[x<<1|1]=cov[x]; cov[x]=-1; } } void update(int op,int L,int R,int l,int r,int x) { if(L<=l&&r<=R) { cov[x]=op; return; } cut(x); int m=(l+r)>>1; if(L<=m)update(op,L,R,left); if(R>m)update(op,L,R,right); } void query(int l,int r,int x) { if(cov[x]!=-1) { int i; for(i=l;i<=r;i++)seg[i]=cov[x]; return; } if(l==r)return; cut(x); int m=(l+r)>>1; query(left); query(right); } int main(void) { int i,j,ansl,ansr,n,t; char c; while(~scanf("%d",&n)) { init(); for(i=0;i<n;i++) { scanf("%d%d",&e[i].a,&e[i].b); myx[cnt++]=e[i].a; myx[cnt++]=e[i].b; c=getchar(); while(c!='w'&&c!='b')c=getchar(); e[i].c=c; } sort(myx,myx+cnt); t=1; for(i=1;i<cnt;i++) if(myx[i]!=myx[i-1])myx[t++]=myx[i]; cnt=t; for(i=1;i<t;i++) { if(myx[i]-myx[i-1]>1)myx[cnt++]=myx[i-1]+1; if(myx[i]-myx[i-1]>2)myx[cnt++]=myx[i]-1; } sort(myx,myx+cnt); myx[cnt++]=eps; for(i=0;i<n;i++) { e[i].a=find(myx,myx+cnt,e[i].a)-myx; e[i].b=find(myx,myx+cnt,e[i].b)-myx; update(e[i].c=='b',e[i].a,e[i].b,0,cnt-1,1); } query(0,cnt-1,1); for(i=0;i<cnt;) if(seg[i]==0) { j=i; while(j<cnt&&seg[i]==seg[j])j++; if(myx[j-1]-myx[i]+1>leng) { leng=myx[j-1]-myx[i]+1; ansl=myx[i]; ansr=myx[j-1]; } i=j; } else i++; if(leng)printf("%d %d\n",ansl,ansr); else puts("0"); } return 0; }