POJ2481Cows(树状数组)

来源:互联网 发布:网络光端机价格 编辑:程序博客网 时间:2024/05/17 05:57

题意:就是给出N个区间,问这个区间是多少个区间的真子集。

分析:关键在于排序的策略。一边固定类型的题目。

#include<iostream>#include<algorithm>#include<cstdio>#include<cstring>using namespace std;const int maxn = 100005;int C[maxn], ans[maxn];struct Cow{    int low, high, index;}cow[maxn];bool cmp(Cow p, Cow q){    if(p.high == q.high)        return p.low < q.low;    return p.high > q.high;}int lowbit(int lo){    return lo & (-lo);}void modify(int pos, int value){    while(pos < maxn)    {        C[pos] += value;        pos += lowbit(pos);    }}int getsum(int pos){    int sum = 0;    while(pos > 0)    {        sum += C[pos];        pos -= lowbit(pos);    }    return sum;}int main(){    int n;    while(cin >> n && n)    {        for(int i = 1; i <= n; i++)        {            scanf("%d%d", &cow[i].low, &cow[i].high);            cow[i].low++;       //注意可能为0,所以加1            cow[i].index = i;        }        sort(cow + 1, cow + n + 1, cmp);        memset(C, 0, sizeof(C));        ans[cow[1].index] = 0;        modify(cow[1].low, 1);        for(int i = 2; i <= n; i++)        {            if(cow[i-1].low == cow[i].low && cow[i].high == cow[i-1].high)                ans[cow[i].index] = ans[cow[i-1].index];            else                ans[cow[i].index] = getsum(cow[i].low);            modify(cow[i].low, 1);        }        for(int i = 1; i < n; i++)            printf("%d ", ans[i]);        printf("%d\n", ans[n]);    }    return 0;}


0 0