题目链接:点击打开链接
线段树离散化区间染色。
数据范围是int最大值,肯定要离散化,离散化时要注意加点。
举几个个例子:
1. 输入 1,2,4,5,如果离散成1,2,3,4那么本来最长区间是1到2,离散后就变成1到4了,这就要在2和4之间加点。
2. 输入 1 5 w,3 5 b,最长区间应是1到2,但是不加点的话没有点表示2,得不到1到2这个结果,需要添加点2
3. 输入 1 5 w,1 3 b,最长区间是4到5,同理需要加4这个点
综上,离散化的步骤是先对原数组排序(代码中用tmp表示),然后加上这两句:
if(tmp[i]-tmp[i-1]>1) Hash[++k]=tmp[i]-1;
if(tmp[i]-tmp[i-1]>2) Hash[++k]=tmp[i-1]+1;
另外统计结果的方法是遍历叶子节点,找最长区间,所以此线段树不需要pushup,只需要能把改变传到下面的pushdown即可。
代码:
#include <iostream> #include <cstring> #include <cstdio> #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #include <algorithm> using namespace std; #define MAX 30000 int Hash[MAX*2]; int res[MAX<<2]; int col[MAX<<2]; int ans[MAX*2]; struct seg{ int s,t; int c; }p[MAX]; void pushdown(int rt){ if(col[rt]){ col[rt<<1]=col[rt<<1|1]=col[rt]; res[rt<<1]=res[rt<<1|1]=col[rt]; col[rt]=0; } } void build(int l,int r,int rt){ col[rt]=0; res[rt]=2; if(l==r) return ; int m=(l+r)>>1; build(lson); build(rson); } void update(int L,int R,int c,int l,int r,int rt){ if(L<=l&&R>=r){ res[rt]=c; col[rt]=c; return ; } pushdown(rt); int m=(l+r)>>1; if(L<=m) update(L,R,c,lson); if(R>m) update(L,R,c,rson); } void query(int l,int r,int rt){ if(l==r){ ans[l]=res[rt]; return ; } int m=(l+r)>>1; query(lson); query(rson); } void solve(int n){ long long tmp[MAX*2]; int len=0; for(int i=1;i<=n;i++){ char c[4]; scanf("%d%d%s",&p[i].s,&p[i].t,c); tmp[++len]=p[i].s; tmp[++len]=p[i].t; if(c[0]=='w') p[i].c=1; else p[i].c=2; } sort(tmp+1,tmp+len+1); int k=0; Hash[++k]=tmp[1]; for(int i=2;i<=len;i++){ Hash[++k]=tmp[i]; if(tmp[i]-tmp[i-1]>1) Hash[++k]=tmp[i]-1; if(tmp[i]-tmp[i-1]>2) Hash[++k]=tmp[i-1]+1; } sort(Hash+1,Hash+k+1); len=unique(Hash+1,Hash+k+1)-Hash-1; build(1,len,1); for(int i=1;i<=n;i++){ int s=lower_bound(Hash+1,Hash+len+1,p[i].s)-Hash; int t=lower_bound(Hash+1,Hash+len+1,p[i].t)-Hash; if(s>t) continue; update(s,t,p[i].c,1,len,1); } query(1,len,1); int answer=-1; int l=0,r=0; bool flag=0; for(int i=1;i<=len;i++){ int j=i; if(ans[i]==1){ flag=1; int tmp=0; while(j<len&&ans[j+1]==1){ j++; } tmp=Hash[j]-Hash[i]; if(tmp>answer){ answer=tmp; l=Hash[i]; r=Hash[j]; } } i=j; } if(!flag) printf("0\n"); else printf("%d %d\n",l,r); } int main(){ int n; while(~scanf("%d",&n)){ solve(n); } return 0; }