Cows POJ - 2481 (树状数组应用-求区间个数)

Cows

 POJ - 2481 

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: cow i and cow j, their favourite clover range is [Si, Ei] and [Sj, Ej]. If Si <= Sj and Ej <= Ei and Ei - Si > Ej - Sj, we say that cow i is stronger than cow j. 

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 <= 10 5), which is the number of cows. Then come N lines, the i-th of which contains two integers: S and E(0 <= S < E <= 10 5) 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 cow i. 

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.

题意:输入n组数据,每组为一个区间,求第i个区间的真子集的个数,案例中:第一个区间【1,2】,第二个【0,3】,第三个【3,4】,输出:比第一个区间大的有1个,比第二个区间大的有0,第三也为0.

思路:刚接触树状数组,说实话理解的还不够清晰。这个题的思路是这样的:首先进行对各个【x,y】进行排序,按照y从大到小,当y相等时按照x先小后大的顺序。比如输入的四个区间为【2,4】【1,4】【0,3】【1,6】,排序后【2,7】【2,5】【3,5】【1,4】(为了避免树状数组中0的情况所有的数都加了1),树状数组中存放的是各个区间中左区间的值(树状数组是根据右区间生成的),当i>j时,c[i]代表的区间是c[j]的真子集,因为按顺序存放的时候,先放【2,7】,再放【2,5】,并且每个位置刚放入时,其下的所有位置的值都加1,因为其下的位置是当前位置的真子集。讲的不怎么清楚,自己能勉强看懂,希望看到本文的同学再去搜一下大佬的博客,我还是太弱啦,还要努力呀。

AC代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#include<utility>
#include<set>
#include<vector>
#include<map>
#include<queue>
#include<stack>
#define maxn 100010
#define INF 0x3f3f3f3f
#define LL long long
#define ULL unsigned long long
#define E 1e-8
#define mod 1000000007
#define P pair<int,int>
using namespace std;

int n;
int tree[maxn];
int ans[maxn];

struct node
{
    int x,y,id;
}a[maxn];
bool cmp(node a,node b)
{
    if(a.y!=b.y) return a.y>b.y;
    return a.x<b.x;
}
int lowbit(int x)
{
    return x&(-x);
}
void add(int x,int y)
{
    for(int i=x;i<=n;i+=lowbit(i)){
        tree[i] += y;
    }
}
LL getsum(int x)
{
    int ans = 0;
    for(int i=x;i>0;i-=lowbit(i)){
        ans+=tree[i];
    }
    return ans;
}

int main()
{
    while(scanf("%d",&n)!=EOF&&n){
        memset(tree,0,sizeof(tree));
        memset(ans,0,sizeof(ans));
        memset(a,0,sizeof(a));
        for(int i=1;i<=n;++i){
            scanf("%d %d",&a[i].x,&a[i].y);
            a[i].x++;a[i].y++; //树状数组中要避免出现0的情况
            a[i].id = i;
        }
        sort(a+1,a+n+1,cmp);
        
        /*for(int i=1;i<=n;++i){
            printf("%d %d \n",a[i].x,a[i].y);
        }*/
        for(int i=1;i<=n;++i){
            if(a[i].x==a[i-1].x&&a[i].y==a[i-1].y)
                ans[a[i].id] = ans[a[i-1].id];
            else ans[a[i].id] = getsum(a[i].x);
            add(a[i].x,1);
        }
        for(int i=1;i<=n;++i){
            printf("%d ",ans[i]);
        }
        printf("\n");
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值