POJ-2481 Cows

抽象模型求许多区间中某个区间是多少个区间的真子区间。

解决思路:刚拿到这个题似乎无从下手,很难表达区间的包含关系。 但实际上一维的包含关系,可以转化为二维的位置关系。对于区间[x1,y1]与[x2,y2],如果[x1,y1]是[x2,y2]的真子区间,那么x1>x2,y1<y2,可知(x2,y2)这个点在(x1,y1)的左上方。那么求某个点某个方向有多少个点,参考HDU 1541 Stars 这道题。将所有点全部记录后,按照某个坐标轴先序排序,再一个一个去处理记录,用树状数组实现。

注意点:
  1. 数据为0的情况,这是树状数组一般都需要注意的一点。
  2. 可能有两个区间完全一样,从题意中可以看出是不能加上的,反馈到二维点上,就是两个点重叠。由于我们是一个一个点来取出处理,那么只要处理时发现与上一个刚处理一样的话,直接令其与上一个点一样就可以了。
//POJ 2481 Cows
//AC 2016-3-21
//Binary array
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cctype>
#include <cstdlib>
#include <cstring>
#include <vector>
#include <set>
#include <string>
#include <map>
#include <queue>
#include <deque>
#include <list>
#include <sstream>
#include <stack>
using namespace std;

#define cls(x) memset(x,0,sizeof x)
#define inf(x) memset(x,0x3f,sizeof x)
#define neg(x) memset(x,-1,sizeof x)
#define ninf(x) memset(x,0xc0,sizeof x)
#define INF 0x3f3f3f3f
#define lowbit(x) x&(-x)
#define bug cout<<"here"<<endl;
//#define debug

struct ox
{
    int s;
    int e;
    int no;
}p;
vector<ox> cows;
int strong[100500];
int treeray[100500];

void tadd(int x,int c)
{
    while(x<100500)
    {
        treeray[x]+=c;
        x+=lowbit(x);
    }
    return;
}

int tread(int x)
{
    int sum=0;
    while(x>0)
    {
        sum+=treeray[x];
        x-=lowbit(x);
    }
    return sum;
}

bool com(const ox &a,const ox &b)
{
    if(a.e==b.e)
        return a.s<b.s;
    return a.e>b.e;
}

int main()
{
    #ifdef debug
        freopen("E:\\Documents\\code\\input.txt","r",stdin);
        freopen("E:\\Documents\\code\\output.txt","w",stdout);
    #endif
    int N=0;
    while(scanf("%d",&N)!=EOF&&N)
    {
        cows.clear();
        cls(treeray);
        cls(strong);
        for(int i=1;i<=N;++i)
        {
            scanf("%d %d",&p.s,&p.e);
            ++p.s;
            ++p.e;
            p.no=i;
            cows.push_back(p);
        }
        sort(cows.begin(),cows.end(),com);
        strong[cows[0].no]=tread(cows[0].s);
        tadd(cows[0].s,1);
        for(vector<ox>::iterator itc=cows.begin()+1;itc!=cows.end();++itc)
        {
            if(itc->s==(itc-1)->s&&itc->e==(itc-1)->e) //这里去重
                strong[itc->no]=strong[(itc-1)->no];
            else
                strong[itc->no]=tread(itc->s);
            tadd(itc->s,1);
        }
        for(int i=1;i<=N;++i)
            printf("%d%c",strong[i],(i==N?'\n':' '));
    }
    return 0;
}


转载于:https://www.cnblogs.com/DrCarlluo/p/6580622.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值