#树状数组# POJ 2481 Cows

版权声明:本文为博主原创文章,转载清注明出处 https://blog.csdn.net/Jasmineaha/article/details/81474680

Description

Farmer John's cows have discovered that the clover growing along the ridge of the hill (which we can think of as a one-dimensional number line) in his field is particularly good. 

Farmer John has N cows (we number the cows from 1 to N). Each of Farmer John's N cows has a range of clover that she particularly likes (these ranges might overlap). The ranges are defined by a closed interval [S,E]. 

But some cows are strong and some are weak. Given two cows: cowi and cowj, their favourite clover range is [Si, Ei] and [Sj, Ej]. If Si <= Sj and Ej <= Ei and Ei - Si > Ej - Sj, we say that cowi is stronger than cowj. 

For each cow, how many cows are stronger than her? Farmer John needs your help!

Input

The input contains multiple test cases. 
For each test case, the first line is an integer N (1 <= N <= 105), which is the number of cows. Then come N lines, the i-th of which contains two integers: S and E(0 <= S < E <= 105) specifying the start end location respectively of a range preferred by some cow. Locations are given as distance from the start of the ridge. 

The end of the input contains a single 0.

Output

For each test case, output one line containing n space-separated integers, the i-th of which specifying the number of cows that are stronger than cowi. 

Sample Input

3
1 2
0 3
3 4
0

Sample Output

1 0 0

Description:

有n头牛,每头牛对应一个区间 [Si,Ei],如果牛j 的区间是牛 i 的区间的真子集( j 区间小于 i 区间且不重合),那么就说牛i 比牛j 强壮,计算每头牛有多少头牛比他强壮

Solution:

首先对区间进行排序,排序规则为:按区间的右端点从大到小排序,如果右端点相同,则左端点小的排在前面

那么当读取到第 i 个牛的 Si 和 Ei时,之前(假设任意两个区间不会完全相同)的牛的 Sj(j<=i-1) <= Si 的这些牛就都比 i 号牛强壮了。枚举区间,不断插入区间左端点,因为区间右端点是保持递减的,所以对于某个区间(Si, Ei),只需要查询树状数组中 [1, Si] 这一段有多少已经插入的数据,就能知道有多少个区间是比它大的,这里需要注意的是多个区间相等的情况,因为有排序,所以它们在排序后的数组中一定是相邻的,所以在遇到有相等区间的情况时,当前的区间的答案就等于上一个相等的区间的答案。

由于树状数组不能含有0元,需要对每个区间的左右端点进行加1.

Code:

#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
#define Fio ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define fopen freopen("in.txt", "r", stdin); freopen("out.txt", "w", stdout);
#define mst(a, b) memset(a, b, sizeof(a))
#define _rush() int T; cin >> T; while(T--)
#define rush() int T; scanf("%d", &T); while(T--)
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
const int INF = 0x3f3f3f3f;
const double eps = 1e-9;
const int Mod = 1e9 + 7;
const int MaxN = 1e5 + 5;

struct node {
	int s, e, id;
}a[MaxN];

int presum[MaxN], ans[MaxN];
int n;

bool cmp(node x, node y) {
	if(x.e == y.e) return x.s < y.s;
	return x.e > y.e;
}

int lowbit(int x) { return x & (-x); }

void add(int p, int x) {
	for(int i = p; i <= n; i += lowbit(i)) presum[i] += x;
}
int sum(int p) {
	int ans = 0;
	for(int i = p; i > 0; i -= lowbit(i)) ans += presum[i];
	return ans;
}

int main()
{
	//Fio;

	while(scanf("%d", &n) != EOF) {
		if(n == 0) return 0;
		mst(presum, 0);
		for(int i = 1; i <= n; i++) {
			int s, e; scanf("%d %d", &s, &e);
			a[i].s = s + 1, a[i].e = e + 1;
			a[i].id = i;
		}
		sort(a + 1, a + 1 + n, cmp);
		for(int i = 1; i <= n; i++) {
			if(i != 1 && a[i].s == a[i-1].s && a[i].e == a[i-1].e) ans[a[i].id] = ans[a[i-1].id];
			else ans[a[i].id] = sum(a[i].s);
			add(a[i].s, 1);
		}
		for(int i = 1; i <= n; i++) 
			cout << ans[i] << " ";
		cout << endl;
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/Jasmineaha/article/details/81474680
今日推荐