poj2481_树状数组

题意:FJ有n头牛(编号为1~n),每一头牛都有一个测验值[S, E],如果对于牛i和牛j来说,它们的测验值满足下面的条件则证明牛i比牛j强壮:Si <= Sj and Ej <= Ei and Ei - Si > Ej - Sj。现在已知每一头牛的测验值,要求输出每头牛有几头牛比其强壮。

分析:将[s,e]看成是而为坐标轴的横纵坐标,画出各个点,我们发现答案就是每个点左上的点的个数。将e降序,再将s升序,就可以转化成一维。

例如:

1 2
1 2
0 3
3 4,排序后为

3 4
0 3
1 2
1 2,这样就转化成横坐标前面小于它的个数。

这个题离散到大于等于1的范围内即可。

难点是,对重复坐标的处理,之前做过的题都是不会有重复的。

重复的点直接拷贝答案就行,不用getsum().

代码:

View Code
 1 #include <stdio.h>

 2 #include <iostream>

 3 #include <memory.h>

 4 #include <algorithm>

 5 using namespace std;

 6 const int maxnum=100005;

 7 struct node

 8 {

 9     int l,r;

10     int pos;

11 }array[maxnum];

12 int tree[maxnum];

13 int ans[maxnum];

14 int n;

15 

16 bool cmp(struct node a,struct node b)

17 {

18     if(a.r==b.r)

19         return a.l<b.l;

20     return a.r>b.r;

21 }

22 

23 void update(int index,int add)

24 {

25     while(index<=maxnum)  //因为没有紧凑化,所以<=maxn;如果紧凑化到n个散列号的话,<=n就可以了

26     {

27         tree[index]+=add;

28         index+=(-index)&index;

29     }

30 }

31 

32 int getsum(int index)

33 {

34     int sum=0;

35     while(index>0)

36     {

37         sum+=tree[index];

38         index-=(-index)&index;

39     }

40     return sum;

41 }

42 

43 int main()

44 {

45     int i;

46     while(scanf("%d",&n) && n!=0)

47     {

48         for(i=0;i<n;i++)

49         {

50             scanf("%d%d",&array[i].l,&array[i].r);

51             array[i].pos=i;

52         }

53         sort(array,array+n,cmp);

54         memset(tree,0,sizeof(tree));

55         int cnt=0;

56         for(i=0;i<n;i++)

57         {

58             if(i!=0 && array[i].l==array[i-1].l && array[i].r==array[i-1].r)

59             {

60                 ans[array[i].pos]=ans[array[i-1].pos]; //注意

61                 cnt++;

62             }

63 //            else  这样为什么不行?????求助!!!!

64 //            {

65 //                update(array[i].l+1,1);

66 //                ans[array[i].pos]=getsum(array[i].l+1)-1+cnt;

67 //            }

68             else

69                 ans[array[i].pos]=getsum(array[i].l+1);

70             update(array[i].l+1,1);

71         }

72         for(i=0;i<n-1;i++)

73             printf("%d ",ans[i]);

74         printf("%d\n",ans[i]);

75     }

76     return 0;

77 }

78 

79 /*

80 4

81 1 2

82 1 2

83 0 3

84 3 4

85 */

 

 

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