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

题目链接:点击打开链接

解题思路:

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;
}

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

时间: 2024-07-29 09:19:35

hdu3015 Disharmony Trees(树状数组+排序)的相关文章

Disharmony Trees 树状数组

Disharmony Trees Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Description One day Sophia finds a very big square. There are n trees in the square. They are all so tall. Sophia is very interesting in them.

POJ - 2481 - Cows (树状数组+排序!!)

Cows Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 13304   Accepted: 4407 Description 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 hi

hdu 3015 Disharmony Trees (离散化+树状数组)

Disharmony Trees Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 663    Accepted Submission(s): 307 Problem Description One day Sophia finds a very big square. There are n trees in the square. T

HDU 3015 Disharmony Trees(树状数组)

题意:给你n棵树,每棵树上有两个权值X H 对于X离散化 :3 7 1 5 3 6 -> 2 6 1 4 2 5,对于H一样 然后F = abs(X1-X2)   S=min(H1,H2) 求出每一对F*S的总和 可以看到一边是求每个数与其他数的最小值,一边是求每个数与其他数的差距.因此我们可以排序一边,处理另一边. 我们排序H,因为这样对于固定一个Xi Hi,从小到大每次都是Hi去乘以Xi与剩下的所有X的差的总和. 这样我们就可以使用树状数组维护两个值:每个位置值的个数,每个位置值的总大小,接

Hdu5032 极角排序+树状数组

题目链接 思路:参考了题解.对询问进行极角排序,然后用树状数组维护一下前缀和即可. /* ID: onlyazh1 LANG: C++ TASK: test */ #include<bits/stdc++.h> using namespace std; #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 typedef long long ll; const int maxn=1010; const int maxm=10

POJ2029:Get Many Persimmon Trees(二维树状数组)

Description Seiji Hayashi had been a professor of the Nisshinkan Samurai School in the domain of Aizu for a long time in the 18th century. In order to reward him for his meritorious career in education, Katanobu Matsudaira, the lord of the domain of

HDU Always Cook Mushroom (极角排序+树状数组)

Problem Description Matt has a company, Always Cook Mushroom (ACM), which produces high-quality mushrooms. ACM has a large field to grow their mushrooms. The field can be considered as a 1000 * 1000 grid where mushrooms are grown in grid points numbe

POJ 2029 Get Many Persimmon Trees (二维树状数组)

Get Many Persimmon Trees Time Limit:1000MS    Memory Limit:30000KB    64bit IO Format:%I64d & %I64u SubmitStatusPracticePOJ 2029 Description Seiji Hayashi had been a professor of the Nisshinkan Samurai School in the domain of Aizu for a long time in

Codeforces 12D Ball 树状数组模拟3个元素的排序

题目链接:点击打开链接 #include<stdio.h> #include<iostream> #include<string.h> #include<set> #include<vector> #include<map> #include<math.h> #include<queue> #include<string> #include<stdlib.h> #include<a