在0到10^9的线段上,一开始颜色全白,然后修改多次子区间颜色或黑或白。求最终状态下的白色最长区间。
主要就是离散化,然后就直接用线段树了。刚刚开始学线段树,代码很挫。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <map>
#include <set>
using namespace std;
const int maxn=10010;
int col[maxn],x[maxn];
map <int,int>Index;
set <int,less<int> > set1;
struct Tnode{int l,r,col;}node[maxn*4];
struct extent{int l,r,col;}et[maxn/2];
void Build(int t,int l,int r)
{
node[t].col=1;
node[t].l=l;
node[t].r=r;
if(l==r-1)return;
int mid=(l+r)/2;
Build(t<<1,l,mid);
Build(t<<1|1,mid,r);
}
void Update(int t,int l,int r,int col)
{
if(l==node[t].l&&r==node[t].r)
{
node[t].col=col;
return;
}
if(node[t].col>=0&&node[t].col!=col)
{
node[t<<1].col=node[t<<1|1].col=node[t].col;
node[t].col=-1;
}
int mid=(node[t].l+node[t].r)>>1;
//cout<<mid<<" "<<t<<endl;
if(l>=mid)
{
Update(t<<1|1,l,r,col);
}
else
if(r<=mid)
Update(t<<1,l,r,col);
else
{
Update(t<<1,l,mid,col);
Update(t<<1|1,mid,r,col);
}
}
void Query(int t)
{
if(node[t].col>0)
{
for(int i=node[t].l;i<node[t].r;i++)
{
col[i]=1;//i to i+1 w;
}
return;
}
if(node[t].col<0)
{
if(node[t].l==node[t].r-1)
return ;
Query(t<<1);
Query(t<<1|1);
}
}
void solve(int cnt)
{
int s=0,e=0,ts,te;
// for(int i=0;i<=cnt;i++)
// print("%d %d %d\n",i,x[i],col[i]);
// for(int i=0;i<=cnt;i++)
// cout<<x[i]<<" "<<i<<" "<<col[i]<<endl;
for(int i=1;i<=cnt;i++)
{
ts=x[i];
while(col[i])
i++;
te=x[i];
if(te-ts > e-s)
{
s=ts;
e=te;
}
}
printf("%d %d\n",s,e);
}
int Discretize()
{
int dex=0;
for(set<int>::iterator p=set1.begin();p!=set1.end();++p)
{
//cout<<*p<<endl;
Index[*p]=++dex;
x[dex]=*p;
}
return dex;
}
int main()
{
//freopen("data","r",stdin);
int n;
char s[5];
while(~scanf("%d",&n))
{
Index.clear();
set1.clear();
memset(col,0,sizeof(col));
int l,r,cnt;
set1.insert(0);
set1.insert(1e9);
for(int i=1;i<=n;i++)
{
scanf("%d%d%s",&l,&r,s);
set1.insert(l);
set1.insert(r);
et[i].l=l;
et[i].r=r;
if(s[0]=='b')
et[i].col=0;
else
et[i].col=1;
}
cnt=Discretize();
Build(1,0,cnt);
for(int i=1;i<=n;i++)
{
// cout<<Index[et[i].l]<<" "<<Index[et[i].r]<<" "<<et[i].col<<endl;
Update(1,Index[et[i].l],Index[et[i].r],et[i].col);
}
Query(1);
solve(cnt);
}
return 0;
}

本文介绍了一种使用线段树解决区间染色问题的方法。问题是在0到10^9的线段上进行多次子区间颜色修改,目标是找出最终状态下最长的白色区间。文章详细解释了如何通过离散化和线段树来高效解决这个问题。
417

被折叠的 条评论
为什么被折叠?



