http://poj.org/problem?id=2481 树状数组+优先队列

来源:互联网 发布:seo白帽优化 编辑:程序博客网 时间:2024/06/05 05:19

题意:给你一个区间[S,E],让你求解能够覆盖这个区间的区间的个数;

思路:树状数组+优先队列。我们应该先固定E,即:先按照E从大到小排序,放到优先队列中,然后,每次弹出一个区间,利用树状数组往下查找,即可以找到比能覆盖当前区间的区间的个数,然后在向上更新区间。

#include<iostream>#include<algorithm>#include<queue>#include<cstdio>#include<string.h>#define maxn 100100using namespace std;struct node{    int S;    int E;    int ID;    bool friend operator <(const node &a,const node &b)    {        if(a.E!=b.E)            return a.E<b.E;        return a.S>b.S;    }}Node[maxn];int num[maxn];int num1[maxn];int MAX;priority_queue<node>Q;int low_bit(int x){    return (-x)&x;}int get_sum(int n){    int ans=0;    while(n>0)    {        ans+=num1[n];        n-=low_bit(n);    }    return ans;}void up_date(int n){    while(n<=MAX+1)    {        num1[n]++;        n+=low_bit(n);    }}int main(){    int N;    while(scanf("%d",&N),N)    {        MAX=-1;      memset(num1,0,sizeof(num1));        while(!Q.empty())            Q.pop();        for(int i=0; i<N; i++)        {            scanf("%d%d",&Node[i].S,&Node[i].E);            Node[i].ID=i;            if(MAX<Node[i].E)                MAX=Node[i].E;            Q.push(Node[i]);        }        memset(num,0,sizeof(num));        node  tem,tem1;        tem1=Q.top();        Q.pop();        num[tem1.ID]=0;           up_date(tem1.S+1);        for(int i=1; i<N; i++)        {            tem=Q.top();            Q.pop();            if(tem1.S==tem.S&&tem1.E==tem.E)            {                num[tem.ID]=num[tem1.ID];            }            else              num[tem.ID]=get_sum(tem.S+1);            up_date(tem.S+1);            tem1=tem;        }        for(int i=0; i<N; i++)            if(i==0)                printf("%d",num[i]);            else                printf(" %d",num[i]);        printf("\n");    }    return 0;}/*33 41 20 3*/