poj 2481 Cows (树状数组)

来源:互联网 发布:简单软件开发 编辑:程序博客网 时间:2024/05/02 00:25

小记:之前没做什么修改之前,在poj上提交1393MS AC了。然后在hdu的web diy里提交gnu c++ 超时了、于是不断的改,在输出的地方花费时间太多了。就是为了保证每两个数之间有一个空格,然后末尾没有空格,我在for里面加了一个判断,只要不是末尾就输出一个空格。然后就这样超时了。。 树状数组全用了inline。 改了一下输出之后。poj969MS,hdu web diy 2250MS 都AC了


思路:树状数组的应用的难点就是你要在哪里用树状数组,使得结果是你要的答案。

这里我是对输入的区间先全部存入一个结构体数组,结构体保存每个区间的左右值(L,R),以及输入的次序(id)。

然后对该结构体数组以x坐标从大到小,如果x坐标想等,以y坐标从小到大的顺序排,

inline bool  cmp1(const node& a,const node& b){    if(a.L == b.L)return a.R < b.R;    return a.L > b.L;}

这样做的原因是,我们等下就可以从排好序的数组的最后一个开始算起,对y用树状数组,求得它前面大于等于它的y的数的个数(这里的前面指的是在它前面算过的的数),

ans[a[k].id] = T - 1 - k - sum(a[k].R);

如果当前区间和前面的一个区间是相同的,那么它的结果就是前面的区间的计算结果,

if(k+1<T && a[k].R == a[k+1].R && a[k].L == a[k+1].L){      ans[a[k].id] = ans[a[k+1].id];}

算出来的这个值就是这个区间的answer。


 因为x从小到大,那么就保证了越前面的x越 大,越后面的x越小,我们从最后一个算起,那么只要不是和前面区间相同,那么之前算过的区间中y值大于等于它的区间就都是符合比它牛的条件的。

例如:

1 2

0 3

3 4

排好序后:

3 4

1 2

0 3

从0 3开始算起,3前面没有大于等于它的数,所以0 3的答案是0, 

然后1 2,2前面有个大于它的3,所以1 2的答案是1,

然后3 4,4前面算过的没有大于等于它的数,所以3 4 的答案是0,

用id存入,输出的答案就是1 0 0


因此保证了算法的正确性。


代码:

#include <stdio.h>#include <algorithm>#include <string.h>#define mst(a,b) memset(a,b,sizeof(a))#define MAX_ 100010#define MAX 100010struct node{    int L, R, id;}a[MAX_];int C[MAX_], ans[MAX_];inline int  lowbit(int x){return x&(-x);}inline void  add(int x,int num){    while(x < MAX){        C[x] += num;        x += lowbit(x);    }}inline int  sum(int x){    int cnt = 0;    while(x > 0){        cnt += C[x];        x -= lowbit(x);    }    return cnt;}inline bool  cmp1(const node& a,const node& b){    if(a.L == b.L)return a.R < b.R;    return a.L > b.L;}int main(){    int T, x, y, cnt, i, k, j;    while(scanf("%d",&T),T){        for(i = 0; i < T; ++i){            scanf("%d%d",&x,&y);            a[i].L = x + 1;            a[i].R = y + 1;            a[i].id = i;        }        std::sort(a,a+T,cmp1);        mst(C,0);        for( k = T-1; k > -1; --k){            if(k+1<T && a[k].R == a[k+1].R && a[k].L == a[k+1].L){                ans[a[k].id] = ans[a[k+1].id];            }            else                ans[a[k].id] = T - 1 - k - sum(a[k].R);            add(a[k].R+1,1);        }        for( i = 0; i < T-1; ++i){            printf("%d ",ans[i]);            //if(i!=T-1)printf(" ");        }        printf("%d\n",ans[T-1]);    }    return 0;}


0 0
原创粉丝点击