题意:给你一个区间[S,E],让你求解能够覆盖这个区间的区间的个数;
思路:树状数组+优先队列。我们应该先固定E,即:先按照E从大到小排序,放到优先队列中,然后,每次弹出一个区间,利用树状数组往下查找,即可以找到比能覆盖当前区间的区间的个数,然后在向上更新区间。
#include<iostream>
#include<algorithm>
#include<queue>
#include<cstdio>
#include<string.h>
#define maxn 100100
using 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;
}
/*
3
3 4
1 2
0 3
*/