M.J的blog

algorithm,ACM-ICPC
随笔 - 39, 文章 - 11, 评论 - 20, 引用 - 0
数据加载中……

POJ 2481 Cows【树状数组】

今天联系树状数组,但是我发现我真的很笨,做了好几道了还是不熟。这个题和前边的也没什么分别,是说每个牛有一个区间[s,e],两个牛[s1,e1], [s2,e2],当s1<=s2并且e1>=e2并且e1-s1>e2-s2时,我们说牛1比牛2强,给N个牛的区间,对于每个牛,输出比这个牛强的牛的个数。
还是需要预处理,先对每个牛的e进行降序排序,e相同时对s进行升序排列,这样循环时可以保证后边的牛绝对不比前边的牛强。在循环时,只需找出比当前牛s小的牛的个数。如果遇到特殊情况,即两个牛区间完全一样,赋值就可以了。哎,加油吧~
Code:
 1 #include<iostream>
 2 #include<algorithm>
 3 #include<map>
 4 #define MAX 100002                   
 5 using namespace std;
 6 int c[MAX],ans[MAX],n,imax;
 7 struct cow
 8 {
 9     int l,r,id;
10 }a[MAX];                          
11 bool cmp(cow a,cow b){                
12     if(a.r==b.r)                          //如果两个牛区间右边界相同,按左边界的升序排列
13         return a.l<b.l;  
14     return a.r>b.r;                       //按右边界的降序排列
15 }
16 int lowbit(int t){
17     return t&(t^(t-1));
18 }
19 int sum(int t){
20     int total=0;
21     while(t>0){
22         total+=c[t];
23         t-=lowbit(t);
24     }
25     return total;
26 }
27 void modify(int posi,int key){
28     while(posi<=imax){
29         c[posi]+=key;
30         posi+=lowbit(posi);
31     }
32 }
33 int main()
34 {
35     int i,j,k,n;
36     while(scanf("%d",&n),n){
37         memset(c,0,sizeof(c));
38         imax=0;
39         for(i=1;i<=n;i++){
40             scanf("%d%d",&a[i].l,&a[i].r);
41             a[i].id=i;                                    //每个牛有个id防止排序完顺序变乱
42             ++a[i].l; ++a[i].r;
43             if(imax<a[i].l) imax=a[i].l;                 //用imax表示右边界最大值,即求和时的边界
44         }
45         sort(a+1,a+n+1,cmp);
46         for(i=1;i<=n;++i){
47             if(i==1){
48                 ans[a[i].id]=sum(a[i].l);              //这里注意是ans[a[i].id]而不是ans[i]
49                 modify(a[i].l,1);
50             }
51             else{
52                 if(a[i].l==a[i-1].l&&a[i].r==a[i-1].r) //如果两个牛完全相同,直接赋值
53                     ans[a[i].id]=ans[a[i-1].id];
54                 else
55                     ans[a[i].id]=sum(a[i].l);         //否则找出左边界l比这个牛小的
56                 modify(a[i].l,1);
57             }
58         }
59         for(i=1;i<n;++i)
60             printf("%d ",ans[i]);
61         printf("%d\n",ans[i]);
62     }
63 }
64 

posted on 2010-05-02 21:20 M.J 阅读(408) 评论(0)  编辑 收藏 引用 所属分类: 树状数组


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理