题目分析
定义一个结构体Cow记录其起点、终点、id和“当前相同区间数目”(后面解释)。按照e从大到小、s从小到大的顺序排列,则对于某头牛来说,比它强壮的都排在它前面。但前面可能有与其区间相同的,于是记录前面有几头相同的牛,计算答案时删掉即可。
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<map>
#include<algorithm>
using namespace std;
const int maxn=1e5+5;
struct Cow
{
int s,e,pos,same;
friend bool operator==(const Cow &x,const Cow &y)
{
return x.s==y.s&&x.e==y.e;
}
}cow[maxn];
bool cmp(Cow x,Cow y)
{
if(x.e>y.e) return true;
if(x.e==y.e && x.s<y.s) return true;
return false;
}
int ans[maxn];
int bit[maxn];
int maxb;
int n;
inline int lowbit(int x){return x&-x;}
void add(int x)
{
for(;x<=maxb;x+=lowbit(x)) bit[x]+=1;
}
int getsum(int x)
{
int res=0;
for(;x>0;x-=lowbit(x)) res+=bit[x];
return res;
}
int main()
{
while(cin>>n && n)
{
maxb=-1;
memset(bit,0,sizeof bit);
for(int i=0;i<n;i++)
{
cow[i].pos=i;
cow[i].same=0;
scanf("%d%d",&cow[i].s,&cow[i].e);
cow[i].s++;cow[i].e++;
maxb=max(maxb,cow[i].e);
}
sort(cow,cow+n,cmp);
for(int i=0;i<n;i++)
{
if(i!=0 && cow[i]==cow[i-1]) cow[i].same=cow[i-1].same;
ans[cow[i].pos]=getsum(cow[i].s)-cow[i].same;
cow[i].same++;
add(cow[i].s);
}
for(int i=0;i<n-1;i++) printf("%d ",ans[i]);
cout<<ans[n-1]<<endl;
}
return 0;
}

本文介绍了一种通过自定义结构体Cow和线段树解决区间覆盖问题的方法。具体实现包括定义Cow结构体来记录每头牛的起始点、结束点、编号及相同区间的数目,并采用特定排序方式确保比当前牛更强壮的牛排在其前。通过遍历数组并利用线段树更新和查询相同区间的数量,最终计算出每头牛比它强壮且不位于同一区间的牛的数量。
496

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



