POJ-2481-COWS(树状数组)

Description

Farmer John’s cows have discovered that the clover growing along the ridge of the hill (which we can think of as a one-dimensional number line) in his field is particularly good.

Farmer John has N cows (we number the cows from 1 to N). Each of Farmer John’s N cows has a range of clover that she particularly likes (these ranges might overlap). The ranges are defined by a closed interval [S,E].

But some cows are strong and some are weak. Given two cows: cowi and cowj, their favourite clover range is [Si, Ei] and [Sj, Ej]. If Si <= Sj and Ej <= Ei and Ei - Si > Ej - Sj, we say that cowi is stronger than cowj.

For each cow, how many cows are stronger than her? Farmer John needs your help!
Input

The input contains multiple test cases.
For each test case, the first line is an integer N (1 <= N <= 105), which is the number of cows. Then come N lines, the i-th of which contains two integers: S and E(0 <= S < E <= 105) specifying the start end location respectively of a range preferred by some cow. Locations are given as distance from the start of the ridge.

The end of the input contains a single 0.
Output

For each test case, output one line containing n space-separated integers, the i-th of which specifying the number of cows that are stronger than cowi.
Sample Input

3
1 2
0 3
3 4
0
Sample Output

1 0 0
Hint

Huge input and output,scanf and printf is recommended.

题意:一头牛喜欢吃的草的范围为[ Si, Ei ],如果这个区间包含在另一头牛的区间里,那么就说明另一头牛比这头牛更强壮,求对于第 i 头牛,比它强壮的牛的个数。

就是求一个区间的真子集(注意的是,两头牛的范围可能相同)

思路:
此题和Stars那道题差不多,都是先固定一侧的区间,然后对另一侧区间进行操作。但是这道题固定的是右区间,按照有区间从大到小排序,如果相同,就让左区间从小到大排序。

这样就能保证对于每头牛的右区间都小于等于在之前牛的右区间,那么,只需要找对于当前的牛的左区间,前面比它小的个数就行了。

细节处理:
范围+1,防止树状数组里出现0;
每次找到比当前左区间小的个数的时候还要减一,去除本身;
当遇到两头牛的范围相等时,令答案等于上一头牛的答案即可,无需求和。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<iomanip>
#include<map>
#include<stack>
#include<vector>
#include<queue>
#include<algorithm>
#define max(a,b)   (a>b?a:b)
#define min(a,b)   (a<b?a:b)
#define swap(a,b)  (a=a+b,b=a-b,a=a-b)
#define memset(a)  memset(a,0,sizeof(a))
#define X (sqrt(5)+1)/2.0  //Wythoff
#define Pi acos(-1)
#define e  2.718281828459045
using namespace std;
typedef long long int LL;
const int MAXL(1e5);
const int INF(0x3f3f3f3f);
const int mod(1e9+7);
int dir[4][2]= {{-1,0},{1,0},{0,1},{0,-1}};
struct node
{
    int x,y;
    int order;
} s[MAXL+50];
int ans[MAXL+50];
int c[MAXL+50];
int maxY;
bool cmp(struct node p,struct node q)
{
    if(p.y==q.y)
        return p.x<q.x;
    return p.y>q.y;
}
int lowbit(int k)
{
    return k&(-k);
}
void Update(int i,int v)
{
    while(i<=maxY)
        c[i]+=v,i+=lowbit(i);
}
int Getsum(int i)
{
    int ans=0;
    while(i>0)
        ans+=c[i],i-=lowbit(i);
    return ans;
}
int main()
{
    int n;
    while(~scanf("%d",&n)&&n)
    {
        memset(c);
        for(int i=0; i<n; i++)
        {
            scanf("%d%d",&s[i].x,&s[i].y);
            s[i].x++,s[i].y++;
            maxY=max(maxY,s[i].y);
            s[i].order=i;
        }
        sort(s,s+n,cmp);
        for(int i=0; i<n; i++)
        {
            Update(s[i].x,1);
            if(i==0)
                ans[s[i].order]=Getsum(s[i].x)-1;
            else
            {
                if(s[i].x==s[i-1].x&&s[i].y==s[i-1].y)
                    ans[s[i].order]=ans[s[i-1].order];
                else
                    ans[s[i].order]=Getsum(s[i].x)-1;
            }
        }
        cout<<ans[0];
        for(int i=1; i<n; i++)
            cout<<" "<<ans[i];
        cout<<endl;
    }
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值