URAL1105[Observers Coloring]

离散化+线段树+动规。

CODE:

/*
PROGRAM: $PROGRAM
AUTHOR: Su Jiao
DATE: 2011-11-22
DESCRIPTION:
$DESCRIPTION
*/

#include <iostream>
#include <utility>
#include <algorithm>
using namespace std;

#define end first
#define begin second
#define segment first
#define id second
typedef pair<double,double> segment;
typedef
pair<segment,int> segment_with_id;

int
N;
segment_with_id one[10000+1];
double
t[2][10000+1];
int
rid[10000+1];
int
d2ic;
pair<int,int> d2i[20000+2];
int
tidc;
int
tid[2][10000+1];
double
i2d[20000+2];
double
f[10000+1];
int
pre[10000+1];
int
best_id;
int
st1[(20000+2)*4];
int
st2[(20000+2)*4];
int
answerc;
int
answer[10000+1];

bool
sort_rule(const pair<int,int>& a,const pair<int,int>& b)
{

return
t[a.first][a.second]<t[b.first][b.second];
}

void
insert1(int L,int R,int p,int v,int root=1)
{

if
(L<=p&&p<=R)
{

if
(f[st1[root]]<f[v])
st1[root]=v;
if
(L==R) return;
int
LL=L,LR=(L+R)>>1,Lroot=root<<1;
int
RL=LR+1,RR=R,Rroot=Lroot|1;
insert1(LL,LR,p,v,Lroot);
insert1(RL,RR,p,v,Rroot);
}
}

int
query1(int L,int R,int p,int root=1)
{

if
(p<L) return 0;
else if
(R<=p) return st1[root];
else

{

int
LL=L,LR=(L+R)>>1,Lroot=root<<1;
int
RL=LR+1,RR=R,Rroot=Lroot|1;
int
a=query1(LL,LR,p,Lroot),b=query1(RL,RR,p,Rroot);
return
f[a]>f[b]?a:b;
}
}

void
insert2(int L,int R,int p,int v,int root=1)
{

if
(L<=p&&p<=R)
{

if
(f[st2[root]]-i2d[tid[1][st2[root]]]*2.0<f[v]-i2d[tid[1][v]]*2.0)
st2[root]=v;
if
(L==R) return;
int
LL=L,LR=(L+R)>>1,Lroot=root<<1;
int
RL=LR+1,RR=R,Rroot=Lroot|1;
insert2(LL,LR,p,v,Lroot);
insert2(RL,RR,p,v,Rroot);
}
}

int
query2(int L,int R,int p,int root=1)
{

if
(R<p) return 0;
else if
(p<=L) return st2[root];
else

{

int
LL=L,LR=(L+R)>>1,Lroot=root<<1;
int
RL=LR+1,RR=R,Rroot=Lroot|1;
int
a=query2(LL,LR,p,Lroot),b=query2(RL,RR,p,Rroot);
return
f[a]-i2d[tid[1][a]]*2.0>f[b]-i2d[tid[1][b]]*2.0?a:b;
}
}


int
main()
{

cin>>t[0][0]>>t[1][0]
>>
N;
d2i[d2ic++]=make_pair(0,0),
d2i[d2ic++]=make_pair(1,0);
for
(int i=1;i<=N;i++)
{

cin>>one[i].segment.begin>>one[i].segment.end;
one[i].id=i;
}

sort(one+1,one+N+1);
for
(int i=1;i<=N;i++)
{

t[0][i]=one[i].segment.begin,
t[1][i]=one[i].segment.end;
rid[i]=one[i].id;
d2i[d2ic++]=make_pair(0,i),
d2i[d2ic++]=make_pair(1,i);
}

sort(d2i,d2i+d2ic,sort_rule);
for
(int i=0;i<d2ic;i++)
{

if
(i&&t[d2i[i].first][d2i[i].second]!=t[d2i[i-1].first][d2i[i-1].second]) tidc++;
tid[d2i[i].first][d2i[i].second]=tidc;
i2d[tidc]=t[d2i[i].first][d2i[i].second];
}

f[best_id=0]=0;
for
(int i=1;i<=N;i++)
{

int
npre;
double
nf;
npre=0;
nf=i2d[tid[1][i]]-i2d[tid[0][i]];
if
(nf>f[i])
{

pre[i]=npre;
f[i]=nf;
}

npre=query1(0,tidc,tid[0][i]);
nf=i2d[tid[1][i]]-i2d[tid[0][i]]+f[npre];
if
(nf>f[i])
{

pre[i]=npre;
f[i]=nf;
}

npre=query2(0,tidc,tid[0][i]);
nf=f[npre]-i2d[tid[1][npre]]*2.0+i2d[tid[0][i]]+i2d[tid[1][i]];
if
(nf>f[i])
{

pre[i]=npre;
f[i]=nf;
}

if
(f[i]>f[best_id]) best_id=i;
insert1(0,tidc,tid[1][i],i);
insert2(0,tidc,tid[1][i],i);
}

if
(f[best_id]>=(i2d[tid[1][0]]-i2d[tid[0][0]])*2.0/3.0)
{

answer[answerc=1]=best_id;
while
(pre[answer[answerc]])
{

answer[answerc+1]=pre[answer[answerc]];
answerc++;
}

cout<<answerc<<endl;
for
(int i=1;i<=answerc;i++)
cout<<rid[answer[i]]<<endl;
}

else
cout<<0<<endl;
return
0;
}

留下评论

您的电子邮箱地址不会被公开。 必填项已用 * 标注