題目鏈接:zoj2301
和poj2528做法基本一樣,建議先做poj的那道題
/*zoj2301Color the Ball 線段樹區間成段更新,離散化
題目大意:
一些連續的球,編號從1~2^31-1,最初球都是黑色的
輸入塗色的區間和要塗的顏色,將區間內的球都塗色(端點處的球也塗色)
輸出連續的且都是白色球的最長的區間,相同的話輸出坐標小的
*/
#include
#include
#include
#include
using namespace std;
#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
const int N = 4000;
bool hash[N<<3];
int col[N<<4];
int X[N<<2];
struct node
{
int x,y,c;
node(){}
node(int a, int b, int cc):x(a),y(b),c(cc){}
}s[N<<2];
void pushdown(int rt)
{
if(col[rt] != -1)
{
col[rt<<1] = col[rt<<1|1] = col[rt];
col[rt] = -1;
}
}
void update(int L, int R, int c, int l, int r, int rt)
{
if(L <= l && r <= R)
{
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(col[rt] == 1)
{
for(int i = l; i <= r; i ++)
hash[i] = true;
return;
}
if(col[rt] == 0) return;
int m = (l+r) >> 1;
query(lson);
query(rson);
}
int main()
{
int i,n,j;
while(~scanf("%d",&n))
{
char a[3];
int x,y;
memset(col, 0, sizeof(col));//0表示黑色
memset(hash, false, sizeof(hash));
int m = 0;
for(i = 0; i < n; i ++)
{
scanf("%d%d%s",&x,&y,a);
int c = a[0]=='b'?0:1;
s[i] = node(x, y, c);
X[m++] = x;
X[m++] = y;
}
sort(X, X+m);
int tot = 1;
for(i = 1; i < m; i ++)
if(X[i] != X[i-1]) X[tot++] = X[i];
for(i = tot - 1; i > 0; i --)
if(X[i] != X[i-1] + 1) X[tot++] = X[i-1] + 1;
sort(X, X+tot);
for(i = 0; i < n; i ++)
{
int l = lower_bound(X, X+tot, s[i].x) - X;
int r = lower_bound(X, X+tot, s[i].y) - X;
update(l+1, r+1, s[i].c, 1, tot, 1);
}
query(1, tot, 1);
int ax,ay,alen = -1;
for(i = 0; i <= tot; i ++)//查找長度最長且坐標最小的區間
{
if(hash[i])
{
for(j = i; j <= tot; j ++)
if(!hash[j]) break;
if(X[j-2] - X[i-1] > alen)
{
ax = X[i-1]; ay = X[j-2];
alen = ay - ax;
}
i = j - 1;
}
}
printf("%d %d\n",ax,ay);
}
return 0;
}