Cows题解

农民约翰的奶牛发现,他田里沿着山脊生长的三叶草(我们可以把它想象成一维的数字线)特别好。
农夫约翰有N头奶牛(我们从1到N对奶牛进行编号)。农夫约翰的N头牛都有一系列她特别喜欢的三叶草(这些范围可能重叠)。范围由闭合区间[S,E]定义。
但是有些牛很强壮,有些牛很虚弱。给定两头奶牛:cowi和cowj,它们最喜欢的三叶草品种是[Si,Ei]和[Sj,Ej]。如果Si<=Sj和Ej<=Ei和Ei-Si>Ej-Sj,我们说cowi比cowj强。
每头牛,有多少头牛比她强壮?农夫约翰需要你的帮助!
输入包含多个测试用例。
对于每个测试用例,第一行是整数N(1<=N<=105),这是奶牛的数量。然后是N行,其中第i行包含两个整数:S和E(0<=S<E<=105),分别指定某些奶牛喜欢的范围的开始-结束位置。位置以距山脊起点的距离表示。
输入的末尾包含一个0。

输出
对于每个测试用例,输出一行包含n个空格分隔的整数,其中第i行指定比cowi更强的奶牛数量。

输入
3
1 2
0 3
3 4
0
输出
1 0 0

就是一个需要自己排序并且去重的数星星(不过顺序从左下跑到了左上,当时只看出了星星)
一开始想的是数星星,左端点抽象成x,右端点抽象成y,那么问题就成了这个点的左上有几点
被GGrun带偏了,以为是一个算包含情况加去重的校门外的树,结果半天想不出来,看的题解,然后看明白了

点击查看代码
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
int c[120000];
int b[120000];
struct node{
	int from;
	int to;
	int id;
}a[120000];
bool operator <(const node&a,const node&b){
	if(a.to==b.to) return a.from<b.from;
	else return a.to>b.to;
}
int n,m,k;
int lowbit(int x){
	return x&-x;
}
void add(int x,int add){
	for(int i=x;i<=n;i+=lowbit(i)){
		c[i]+=add;
	}
}
int sum(int x){
	int ans=0;
	for(int i=x;i>0;i-=lowbit(i)){
		ans+=c[i];
	}
	return ans;
}
int main(){
	while(scanf("%d",&n)!=-1&&n){
		for(int i=1;i<=n;i++){
			scanf("%d%d",&a[i].from,&a[i].to);
			a[i].from++;a[i].to++;
			a[i].id=i;
		}
		sort(a+1,a+1+n);
		b[a[1].id]=0;
		add(a[1].from,1);
		for(int i=2;i<=n;i++){
			if(a[i].from==a[i-1].from&&a[i].to==a[i-1].to){
				b[a[i].id]=b[a[i-1].id];
			}
			else b[a[i].id]=sum(a[i].from);
			add(a[i].from,1);
		}
		for(int i=1;i<=n;i++){
			printf("%d ",b[i]);
		}
		printf("\n");
		memset(a,0,sizeof(a));
		memset(c,0,sizeof(c));
		memset(b,0,sizeof(b));
	}
}
posted @ 2024-02-19 09:43  shaoyufei  阅读(15)  评论(0编辑  收藏  举报