来源:http://acm.hdu.edu.cn/showproblem.php?pid=3015
题意:有一些树,这些树的高度和位置给出。现在高度和位置都按从小到大排序,对应一个新的rank,任意两棵树的值为min(高度的rank) * abs(位置差的绝对值)。问所有任意两棵树的值的和是多少。
思路:首先对高度和位置分别离散,接下来就是树状数组 了,和poj 1990是一样的。
代码:
#include <iostream>
#include <cstdio>
#include <string.h>
#include <algorithm>
using namespace std;
const int N = 100010;
struct tree{
int x,height,id;
int xid,hid;
}tt[N],tt1[N],tt2[N];
__int64 numtree[N],len[N];
bool cmp1(tree a,tree b){
return a.x < b.x;
}
bool cmp2(tree a,tree b){
return a.height < b.height;
}
bool cmp3(tree a,tree b){
return a.hid > b.hid;
}
int inline lowbit(int x){
return x & (-x);
}
__int64 inline sum(__int64 temp[N],int x){
__int64 s = 0;
while(x > 0){
s += temp[x];
x -= lowbit(x);
}
return s;
}
void inline update(__int64 temp[N],int x,int add){
while(x < N){
temp[x] += add;
x += lowbit(x);
}
}
int main(){
//freopen("1.txt","r",stdin);
int n;
while(scanf("%d",&n) != EOF){
memset(numtree,0,sizeof(numtree));
memset(len,0,sizeof(len));
for(int i = 1; i <= n; ++i){
scanf("%d%d",&tt[i].x,&tt[i].height);
tt[i].id = i;
tt1[i] = tt2[i] = tt[i];
}
sort(tt1+1,tt1+n+1,cmp1);
int posid = tt1[1].id;
tt1[1].xid = 1;
tt[posid].xid = 1;
for(int i = 2; i <= n; ++i){
posid = tt1[i].id;
if(tt1[i].x == tt1[i-1].x){
tt1[i].xid = tt1[i-1].xid;
tt[posid].xid = tt1[i].xid;
}
else{
tt1[i].xid = i;
tt[posid].xid = tt1[i].xid;
}
}
sort(tt2+1,tt2+n+1,cmp2);
tt2[1].hid = 1;
posid = tt2[1].id;
tt[posid].hid = 1;
for(int i = 2; i <= n; ++i){
posid = tt2[i].id;
if(tt2[i].height == tt2[i-1].height){
tt2[i].hid = tt2[i-1].hid;
tt[posid].hid = tt2[i].hid;
}
else{
tt2[i].hid = i;
tt[posid].hid = tt2[i].hid;
}
}
sort(tt+1,tt+n+1,cmp3);
__int64 ans = 0;
update(numtree,tt[1].xid,1);
update(len,tt[1].xid,tt[1].xid);
for(int i = 2; i <= n; ++i){
__int64 cnt = sum(numtree,tt[i].xid);
__int64 total = sum(len,tt[i].xid);
__int64 alltotal = sum(len,N-1);
ans += tt[i].hid * (cnt * tt[i].xid - total + alltotal - total - (i - cnt - 1) * tt[i].xid);
update(numtree,tt[i].xid,1);
update(len,tt[i].xid,tt[i].xid);
}
printf("%I64d\n",ans);
}
return 0;
}