题目链接:点击打开链接
题意:山坡上长满三叶草,给定一群牛和他们喜爱的范围【S,Ei】,如果一头牛的S小于等于另一头牛而E大于等于另一头牛的,且S和E不同时相等,那么这头牛就比另一头牛强壮。
可以先对E从大到小排序,这样保证遍历时后出现的牛的上界一定满足小于等于前面的,这样只需要判断他的下界满不满足就行,这就想到了用树状数组。
用树状数组c[i]保存到 i 前有多少牛的下界判断过了。
这样对每个牛先把他的下界加进去,再查有多少小于他的下界的牛,答案就是这个数-1(减他自己)
对于判断S和E不同时相等有一个好的办法,就是添加完后先判断当前区间是否和前一个区间完全相同,如果相同就直接让答案等于前一个区间的。因为区间完全相同的一定排在一起且答案相同,这样当第一个加进去的时候此时除他自己以外没有别的妞区间和他完全相同,按上面的算法得到正确的答案,后面每一个就复制他的答案即可。
本题范围是从零开始,直接输入0会在query时引起死循环,所以输入时全部+1
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define MAX 100010
using namespace std;
struct cow{
int s,e,id;
bool operator ==(cow obj){
return s==obj.s&&e==obj.e;
}
}a[MAX];
int res[MAX];
bool cmp(cow a,cow b){
return a.e>b.e||(a.e==b.e&&a.s<b.s);
}
int c[MAX];
int N;
int lowbit(int n){
return n&(-n);
}
void add(int n,int p){
while(p<=MAX) {
c[p]+=n;
p+=lowbit(p);
}
}
int query(int p){
int res=0;
while(p>0){
res+=c[p];
p-=lowbit(p);
}
return res;
}
int main(){
while(~scanf("%d",&N)){
memset(c,0,sizeof(c));
if(!N) break;
for(int i=1;i<=N;i++){
scanf("%d%d",&a[i].s,&a[i].e);
a[i].id=i;
}
sort(a+1,a+N+1,cmp);
for(int i=1;i<=N;i++){
add(1,a[i].s+1);
if(a[i]==a[i-1]){
res[a[i].id]=res[a[i-1].id];
}
else{
res[a[i].id]=query(a[i].s+1)-1;
}
}
for(int i=1;i<N;i++){
printf("%d ",res[i]);
}
printf("%d\n",res[N]);
}
return 0;
}
博客围绕牛的强壮判断问题展开,给定牛喜爱范围【S,Ei】,若一头牛的S小于等于另一头牛且E大于等于另一头牛,且S和E不同时相等,则更强壮。通过对E从大到小排序,利用树状数组判断下界,还给出处理区间相同情况的方法,同时提到输入范围调整。
532

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



