线段树+离散
预处理出每头牛到FJ面前的时间和离开时间,离散后用线段树按时间覆盖,最后统计牛的编号数
注意从y大的开始先覆盖,还有给出的是牛的尾巴坐标,牛头是(x,y+1)。我因为这WA了好几次。。。
代码:
<span style="font-family:SimSun;font-size:14px;">#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int tree[500000*2+10];
struct s
{
int y,w;
}d[500000*2+10];
bool pd[500010];
int now,n,m,i,j,k,x,y,r1;
void insert(int x,int l,int r,int a,int b,int num)//线段树插入
{
int mid=0;
if (tree[x]!=num)
{
mid=(a+b)>>1;
if(a==l&&b==r)tree[x]=num;
else
{
if (tree[x]>=0)
{
tree[x*2]=tree[x];
tree[x*2+1]=tree[x];
tree[x]=-1;
}
if(r<=mid) insert(x*2,l,r,a,mid,num);
else
if(l>=mid) insert(x*2+1,l,r,mid,b,num);
else
{
insert(x*2,l,mid,a,mid,num);
insert(x*2+1,mid,r,mid,b,num);
}
}
}
}
bool cmp1(s i,s j)
{
if (i.w<j.w)return true;
return false;
}
bool cmp2(s i,s j)
{
if(i.y>j.y)return true;
if(i.y==j.y)return i.w<j.w?true:false;
return false;
}
void pan(int x)
{
if(!tree[x])return;
if(tree[x]==-1)
{
pan(x*2),pan(x*2+1);
return;
}
pd[tree[x]]=true;
return;
}
int count()//统计工作
{
pan(1);
int ans=0;
for(int i=1;i<=n;++i)
if(pd[i])++ans;
return ans;
}
int main()
{
scanf("%d",&n);
m=0;
memset(tree,0,sizeof(tree));
memset(pd,false,sizeof(pd));
for(i=1;i<=2*n+4;++i)
{
d[i].w=0;
d[i].y=0;
}
for(i=1;i<=n;++i)
{
scanf("%d%d%d",&x,&y,&r1);
if (y<0) continue;
d[2*++m-1].w=(0-x-1)*r1;
d[2*m].w=(0-x)*r1;
d[2*m-1].y=y;
d[2*m].y=y;
}//离散开始
sort(d+1,d+2*m+1,cmp1);//按时间从小到大排序
now=1;
for(i=2;i<=2*m;++i)
{
if (d[i].w==d[i-1].w)d[i-1].w=now;
else
{
d[i-1].w=now++;
}
}
d[2*m].w=now;//离散结束
sort(d+1,d+2*m+1,cmp2);//按y坐标从大到小排序
for(i=1;i<=m;++i)
{
insert(1,d[i*2-1].w,d[i*2].w,1,now,i);
}
printf("%d",count());
return 0;
}</span>