树状数组-例题

例题1 cows


题目描述:

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: cow i and cow j, their favourite clover range is [Si, Ei] and [Sj, Ej]. If Si <= Sj and Ej <= Ei and Ei - Si > Ej - Sj, we say that cow i is stronger than cow j.

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

输入

The input contains multiple test cases.
For each test case, the first line is an integer N (1 <= N <= 10 5), which is the number of cows. Then come N lines, the i-th of which contains two integers: S and E(0 <= S < E <= 10 5) 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.

输出

The input contains multiple test cases.
For each test case, the first line is an integer N (1 <= N <= 10 5), which is the number of cows. Then come N lines, the i-th of which contains two integers: S and E(0 <= S < E <= 10 5) 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.

样例输入

3
1 2
0 3
3 4
0

样例输出

1 0 0

提示

Huge input and output,scanf and printf is recommended.


题目意思:

给定n各区间,为S1-Sn和E1-En

对于每一个区间[Si,Ei]求出能够覆盖自身的区间的数量

题目思路:

使用树状数组,排序cow(表示每个区间)数组,按E从大到小排序,那么如果E相等,则排序S从小到大排。

那么排序之后的结果cow就保证能覆盖[i,j]这个区间的区间在cow[i]之前。

样例实现:

此处只演示较为复杂的排序部分。

  1. 输入[1 2][0 3][3 4]
  2. 先排序
  3. 排序完后为[3,4][1,2][0,3]
  4. 那么此时能覆盖[1,2]的个数为1,[0,3]的个数为0(不符合S>S),[3,4]的个数为0
  5. 输出1,0,0

此演示省略了判断与查询、更新的部分,请谅解。

源码

#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;

int cas=1,T;
int cnt[100100];
int ans[100010];

struct node{
	int s,e,index;
}cow[100010];

int n;
int lowbit(int x){
	return x&(-x);
}
int sum(int x){
	int ans=0;
	while(x>0){
		ans+=cnt[x];
		x-=lowbit(x);
	}
	return ans;
}
void add(int x,int v){
	while (x<=100010){
		cnt[x]+=v;
		x+=lowbit(x);
	}
}
bool cmp(node a,node b){
    if(a.e!=b.e)
	    return a.e>b.e;
    return a.s<b.s;
}

int main(){
	while(scanf("%d",&n)!=EOF && n){
		memset(ans,0,sizeof(ans));
		memset(cnt,0,sizeof(cnt));
		for(int i=0;i<n;i++){
			scanf("%d%d",&cow[i].s,&cow[i].e);
			cow[i].s++;
			cow[i].e++;
			cow[i].index=i;
		}
		sort(cow,cow+n,cmp);
	    ans[cow[0].index]=sum(cow[0].s);
		add(cow[0].s,1);
		for(int i=1;i<n;i++){
			if (cow[i].s==cow[i-1].s && cow[i].e==cow[i-1].e)
				ans[cow[i].index]=ans[cow[i-1].index];
			else
				ans[cow[i].index]=sum(cow[i].s);
			add(cow[i].s,1);
		}
		for (int i=0;i<n-1;i++)
			printf("%d ",ans[i]);
		printf("%d\n",ans[n-1]);
	}
	return 0;
}

猜你喜欢

转载自www.cnblogs.com/Wolfbeyond/p/9452962.html