P - 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头牛,编号从1—n, 每一头牛都有一个检测值[S, E], 如果对牛x和牛y来说,他们的测验值满足三个条件,则证明牛x比牛y强壮:

① Xs <= Ys  ② Xe >= Ye  ③ Xe - Xs > Ye - Ys;  现在已知每一头牛的测验值,要求输出对于每头牛来说,有几头牛比他强壮

思路:我们可以把牛的S、E看作是二维坐标系中的X、Y轴,那么此题就相当于树状数组的某Stars题,改为求左上角的牛的数量(因为要求si<=sj 且ej≤ei);按照y的降序排列,y相等时,按照x升序排列;


#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<cmath>
#include<stack>
using namespace std;
const int maxn = 100010;
int n, maxx;
int tree[maxn];
int sum[maxn];;
struct Node
{
    int s, e, num;
}node[maxn];

//按照s,e中的e从大到小,如果e相等-s从小到大排序。所以比自己强壮的只能是前面的;
//在二维数组中就是y大的在前,y小的在后,y相同时,x大的在前,x小的在后;
bool cmp(Node p, Node q)
{
    if(p.e==q.e)
    {
        return p.s<q.s;
    }
    return p.e>q.e;
}

//线段树的常规操作;
int lowbit(int x)
{
    return x&(-x);
}
void add(int x, int y)
{
    for(int i=x; i<=n; i+=lowbit(i))
    {
        tree[i] = tree[i]+y;
    }
}
int getsum(int x)
{
    int sum = 0;
    for(int i=x; i>0; i-=lowbit(i))
    {
        sum+= tree[i];
    }
    return sum;
}


int main()
{
    while(scanf("%d", &n)!=EOF&&n)
    {
        for(int i=1; i<=n; i++)
        {
            scanf("%d%d", &node[i].s, &node[i].e);
            node[i].num = i;
        }
        sort(node+1, node+1+n, cmp);
        memset(tree, 0, sizeof(tree));
        memset(sum, 0, sizeof(sum));
        sum[node[1].num] = 0;
        add(node[1].s+1, 1);
        for(int i=2; i<=n; i++)
        {
    //如果第i号牛与上一头牛的e, s都相等,则对于第i个牛来说不如他强壮的就与不如第i-1头牛强壮的牛的数量相等,就不用往下找了;
            if(node[i].e==node[i-1].e&&node[i].s==node[i-1].s)
                sum[node[i].num] = sum[node[i-1].num];

    //否则可以求出覆盖本区间的所有牛的个数,由于排序,只能在前面
    //否则,该点左上角的牛的数量就等于第横坐标加1个区间(本区间)所存的数量;(因为树状数组是从1开始的)
            else
                sum[node[i].num] = getsum(node[i].s+1);
            add(node[i].s+1, 1);//将本区间的起始点加入到树状数组中
        }
        printf("%d", sum[1]);
        for(int i=2; i<=n; i++)
        {
            printf(" %d", sum[i]);
        }
        printf("\n");
    }
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值