码迷,mamicode.com
首页 > 编程语言 > 详细

hdu3015 Disharmony Trees(树状数组+排序)

时间:2015-08-21 11:23:39      阅读:221      评论:0      收藏:0      [点我收藏+]

标签:

题目链接:点击打开链接


解题思路:

1、首先对x和高度h分别从小到大排序记录排名

2、然后对高度h按从大到小排序(保证当前要计算的树的高度是所有已经遍历的树中最小高度,便于计算S=min(h1,h2))

3、循环遍历数组,每次遍历向树状数组C中t[i].rx位置增加t[i].rx,向树状数组C1中t[i].rx位置增加1

解析:C记录排名和,C1记录个数

所以以t[i].rh为最小值的点对的和为

t[i].rh*(sum(n)-sum(t[i].rx)-(LL)t[i].rx*(sum1(n)-sum1(t[i].rx))+(LL)sum1(t[i].rx-1)*t[i].rx-sum(t[i].rx-1));

代码:

#include <cstdio>
#include <algorithm>
#include <cstring>
#define MAXN 100010
using namespace std;
typedef unsigned long long LL;
struct tree{
    int x;
    int h;
    int rx;
    int rh;
}t[MAXN];
LL C[MAXN];
int C1[MAXN];
int rx,rh;
int n;
bool cmp1(tree a,tree b){
    return a.x<b.x;
}
bool cmp2(tree a,tree b){
    return a.h<b.h;
}
bool cmp3(tree a,tree b){
    return a.h>b.h;
}
int lowbit(int x){
    return x&(-x);
}
LL sum(int pos){
    LL ret=0;
    while(pos>0){
        ret+=C[pos];
        pos-=lowbit(pos);
    }
    return ret;
}
void add(int pos,int v){
    while(pos<=n){
        C[pos]+=v;
        pos+=lowbit(pos);
    }
}
int sum1(int pos){
    int ret=0;
    while(pos>0){
        ret+=C1[pos];
        pos-=lowbit(pos);
    }
    return ret;
}
void add1(int pos,int v){
    while(pos<=n){
        C1[pos]+=v;
        pos+=lowbit(pos);
    }
}
int main(){
    while(scanf("%d",&n)!=EOF){
        rx=rh=1;
        for(int i=0;i<n;++i)
            scanf("%d%d",&t[i].x,&t[i].h);
            sort(t,t+n,cmp1);
            t[0].rx=rx++;
            for(int i=1;i<n;++i){
                if(t[i].x==t[i-1].x)
                    t[i].rx=t[i-1].rx;
                else
                    t[i].rx=rx;
                rx++;
            }
            sort(t,t+n,cmp2);
            t[0].rh=rh++;
            for(int i=1;i<n;++i){
                if(t[i].h==t[i-1].h)
                    t[i].rh=t[i-1].rh;
                else
                    t[i].rh=rh;
                rh++;
            }
            sort(t,t+n,cmp3);
            memset(C,0,sizeof(C));
            memset(C1,0,sizeof(C1));
            LL ans=0;
            for(int i=0;i<n;++i){
                add(t[i].rx,t[i].rx);
                add1(t[i].rx,1);
                ans+=t[i].rh*(sum(n)-sum(t[i].rx)-(LL)t[i].rx*(sum1(n)-sum1(t[i].rx))+(LL)sum1(t[i].rx-1)*t[i].rx-sum(t[i].rx-1));
            }
            printf("%I64u\n",ans);
    }
    return 0;
}




版权声明:本文为博主原创文章,未经博主允许不得转载。

hdu3015 Disharmony Trees(树状数组+排序)

标签:

原文地址:http://blog.csdn.net/mengxingyuanlove/article/details/47830597

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!