POJ 2481 Cows (树状数组)

题意:给定n个区间,问每个区间所覆盖的区间的个数。

思路:第三道树状数组,终于有感觉了,要不就傻X了,对区间排序,然后树状数组查询,思路和Stars那道差不多,不过还要处理重合区间的情况,只需排序后O(N)扫描一遍就好了。

  
    
/* Cows 2481
* 树状数组第三题,对牛排序即可 ,注意要
* 排除体型相等的牛.
*/
#include
< iostream >
#include
< cstdio >
#include
< algorithm >
#include
< memory.h >
#include
< cmath >
#include
< bitset >
#include
< queue >
#include
< vector >
using namespace std;

const int BORDER = ( 1 << 20 ) - 1 ;
const int MAXSIZE = 37 ;
const int MAXN = 100200 ;
const int INF = 1000000000 ;
#define CLR(x,y) memset(x,y,sizeof(x))
#define ADD(x) x=((x+1)&BORDER)
#define IN(x) scanf("%d",&x)
#define OUT(x) printf("%d\n",x)
#define MIN(m,v) (m)<(v)?(m):(v)
#define MAX(m,v) (m)>(v)?(m):(v)
#define ABS(x) ((x)>0?(x):-(x))

typedef
struct {
int s,e;
int id;
}Node;

Node node[MAXN];
int tre[MAXN],n_tre;
int n;
int ans[MAXN],same[MAXN];

int lowbit( int x)
{
return x & ( - x);
}
void modify( int ind, int delta)
{
while ( ind <= n_tre)
{
tre[ind]
+= delta;
ind
+= lowbit(ind);
}
}
int get_sum( int ind)
{
int sum = 0 ;
while (ind > 0 )
{
sum
+= tre[ind];
ind
-= lowbit(ind);
}
return sum;
}
bool cmp( const Node & a, const Node & b)
{
if (a.e == b.e)
return a.s < b.s;
return a.e > b.e;
}
int init()
{
n_tre
= 100400 ;
CLR(same,
0 );
CLR(tre,
0 );
CLR(ans,
0 );
return 0 ;
}
int input()
{
for ( int i = 0 ; i < n; ++ i)
{
scanf(
" %d%d " , & node[i].s, & node[i].e);
++ node[i].s;
++ node[i].e;
node[i].id
= i;
}
return 0 ;
}
int _find_same()
{
int i,j,tmp;
for (i = 1 ; i < n; ++ i)
{
tmp
= 0 ;
if (node[i - 1 ].s == node[i].s && node[i - 1 ].e == node[i].e)
same[i]
= same[i - 1 ] + 1 ;
}
return 0 ;
}
int work()
{
int i,j,s,e,tmp;
sort(node,node
+ n,cmp);
_find_same();
for (i = 0 ; i < n; ++ i)
{
ans[node[i].id]
= get_sum(node[i].s) - same[i];
modify(node[i].s,
1 );
}
printf(
" %d " ,ans[ 0 ]);
for (i = 1 ; i < n; ++ i)
printf(
" %d " ,ans[i]);
printf(
" \n " );
return 0 ;
}
int main()
{
while (IN(n))
{
if ( ! n)
break ;
init();
input();
work();
}
return 0 ;
}

 

你可能感兴趣的:(树状数组)