题意:有n头牛,每头牛对应一个区间[Si,Ei],如果牛j 的区间是牛i 的区间的真子集(即Si <= Sj and Ej <= Ei and Ei - Si > Ej - Sj),那么就说牛i 比牛j 强壮。要你依次输出比第i头牛强壮的牛数目。
思路:如果将所有牛的E区间按从大到小排序(如果E相同,则S小的排在前面)的话,那当前读取到第i个牛的Si和Ei,那么之前(假设任意牛的区间不会完全相同)的牛的Sj(j<=i-1)<=Si的这些牛就都比i号牛强壮了。可以理解为之前那道star的题,固定一个维度,剩下的就是看剩下的那一个维度了。
Trick:这里有可能有两个区间一模一样的,那么就直接赋值即可了
#include <cstdio>
#include <queue>
#include <cstring>
#include <iostream>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <map>
#include <string>
#include <set>
#include <ctime>
#include <cmath>
#include <cctype>
using namespace std;
#define maxn 100000+100
#define LL long long
int cas=1,T;
int c[maxn];
int lowbit(int x)
{
return x&(-x);
}
int sum(int x)
{
int ans = 0;
while (x)
{
ans+=c[x];
x-=lowbit(x);
}
return ans;
}
void add(int x,int v)
{
while (x <= maxn)
{
c[x]+=v;
x+=lowbit(x);
}
}
struct Node
{
int s,e;
int id;
}cow[maxn];
int ans[maxn];
int n;
bool cmp(Node a,Node b)
{
return a.e>b.e || (a.e==b.e && a.s<b.s);
}
int main()
{
while (scanf("%d",&n)!=EOF && n)
{
for (int i = 1;i<=n;i++)
{
int s,e;
scanf("%d%d",&s,&e);
s++;
cow[i].s=s;
cow[i].e=e;
cow[i].id=i;
}
sort(cow+1,cow+n+1,cmp);
memset(ans,0,sizeof(ans));
memset(c,0,sizeof(c));
ans[cow[1].id]=0;
add(cow[1].s,1);
for (int i = 2;i<=n;i++)
{
if (cow[i].s==cow[i-1].s && cow[i].e==cow[i-1].e)
ans[cow[i].id]=ans[cow[i-1].id];
else
ans[cow[i].id] = sum(cow[i].s);
add(cow[i].s,1);
}
for (int i = 1;i<=n;i++)
printf("%d ",ans[i]);
printf("\n");
}
//freopen("in","r",stdin);
//scanf("%d",&T);
//printf("time=%.3lf",(double)clock()/CLOCKS_PER_SEC);
return 0;
}