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!
Input
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.
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 cow i.
Sample Input
3 1 2 0 3 3 4 0
Sample Output
1 0 0
Hint
Huge input and output,scanf and printf is recommended.
题意:输入n组数据,每组为一个区间,求第i个区间的真子集的个数,案例中:第一个区间【1,2】,第二个【0,3】,第三个【3,4】,输出:比第一个区间大的有1个,比第二个区间大的有0,第三也为0.
思路:刚接触树状数组,说实话理解的还不够清晰。这个题的思路是这样的:首先进行对各个【x,y】进行排序,按照y从大到小,当y相等时按照x先小后大的顺序。比如输入的四个区间为【2,4】【1,4】【0,3】【1,6】,排序后【2,7】【2,5】【3,5】【1,4】(为了避免树状数组中0的情况所有的数都加了1),树状数组中存放的是各个区间中左区间的值(树状数组是根据右区间生成的),当i>j时,c[i]代表的区间是c[j]的真子集,因为按顺序存放的时候,先放【2,7】,再放【2,5】,并且每个位置刚放入时,其下的所有位置的值都加1,因为其下的位置是当前位置的真子集。讲的不怎么清楚,自己能勉强看懂,希望看到本文的同学再去搜一下大佬的博客,我还是太弱啦,还要努力呀。
AC代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#include<utility>
#include<set>
#include<vector>
#include<map>
#include<queue>
#include<stack>
#define maxn 100010
#define INF 0x3f3f3f3f
#define LL long long
#define ULL unsigned long long
#define E 1e-8
#define mod 1000000007
#define P pair<int,int>
using namespace std;
int n;
int tree[maxn];
int ans[maxn];
struct node
{
int x,y,id;
}a[maxn];
bool cmp(node a,node b)
{
if(a.y!=b.y) return a.y>b.y;
return a.x<b.x;
}
int lowbit(int x)
{
return x&(-x);
}
void add(int x,int y)
{
for(int i=x;i<=n;i+=lowbit(i)){
tree[i] += y;
}
}
LL getsum(int x)
{
int ans = 0;
for(int i=x;i>0;i-=lowbit(i)){
ans+=tree[i];
}
return ans;
}
int main()
{
while(scanf("%d",&n)!=EOF&&n){
memset(tree,0,sizeof(tree));
memset(ans,0,sizeof(ans));
memset(a,0,sizeof(a));
for(int i=1;i<=n;++i){
scanf("%d %d",&a[i].x,&a[i].y);
a[i].x++;a[i].y++; //树状数组中要避免出现0的情况
a[i].id = i;
}
sort(a+1,a+n+1,cmp);
/*for(int i=1;i<=n;++i){
printf("%d %d \n",a[i].x,a[i].y);
}*/
for(int i=1;i<=n;++i){
if(a[i].x==a[i-1].x&&a[i].y==a[i-1].y)
ans[a[i].id] = ans[a[i-1].id];
else ans[a[i].id] = getsum(a[i].x);
add(a[i].x,1);
}
for(int i=1;i<=n;++i){
printf("%d ",ans[i]);
}
printf("\n");
}
return 0;
}