POJ2481-Cows【树状数组】

正题

题目链接:
http://poj.org/problem?id=2481


题目大意

给出若干个区间[Si,Ei],定义一个区间比另一个区间“strong”当且仅当Si<=Sj and Ei>=Ej and Ei-Si>Ej-Sj。输出对于每一个区间,有多少个区间比它strong。区间最多100000个,区间坐标不超过100000。


解题思路

将e从大到小排序,如果e等于就将s从小到大排序。然后用树状数组表示Si==x的数量,然后每次因为e是降序所有只有可能strong与i比其大的牛,然后在s和e都相等的情况下特殊处理就好了。


代码

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
struct co{
    int num,s,e,w;
}cow[100001];
int c[100001],n,maxs;
int lowbit(int x)
{return x&(-x);}
void change(int x,int num)//改变
{
    int i=x;
    while(i<=maxs)
    {
        c[i]+=num;
        i+=lowbit(i);
    }
}
int getsum(int x)//求和
{
    int sum=0;
    while (x>0)
    {
        sum+=c[x];
        x-=lowbit(x);
    }
    return sum;
}
bool cmp(co x,co y)//排序
{
    if (x.e==y.e) return x.s<y.s;
    return x.e>y.e;
}
bool cmp2(co x,co y)//排序回来
{
    return x.num<y.num;
}
int main()
{
    while(true)
    {
      scanf("%d",&n);
      if (!n) break;
      memset(c,0,sizeof(c));
      for (int i=1;i<=n;i++)
      {
        scanf("%d%d",&cow[i].s,&cow[i].e);
        maxs=max(maxs,cow[i].e);
        cow[i].num=i;
      }
      sort(cow+1,cow+1+n,cmp);//排序
      int last=0,k=0;
      for (int i=1;i<=n;i++)
      {
          if (i!=1&&cow[i].e==cow[i-1].e&&cow[i].s==cow[i-1].s)
          {
            cow[i].w=cow[i-1].w;
            change(cow[i].s+1,1);//相等就直接赋值为上一个
          }
          else
          {
            cow[i].w=getsum(cow[i].s+1);
            change(cow[i].s+1,1);
            //插入
          }
      }
      sort(cow+1,cow+1+n,cmp2);
      for (int i=1;i<=n;i++)
        printf("%d ",cow[i].w);
      printf("\n");
    }
}

猜你喜欢

转载自blog.csdn.net/mr_wuyongcong/article/details/80286918
今日推荐