Disharmony Trees (好一个树状数组+离散化)

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.

Disharmony Trees (好一个树状数组+离散化)_第1张图片


She finds that trees maybe disharmony and the Disharmony Value between two trees is associated with two value called FAR and SHORT.

The FAR is defined as the following:If we rank all these trees according to their X Coordinates in ascending order.The tree with smallest X Coordinate is ranked 1th.The trees with the same X Coordinates are ranked the same. For example,if there are 5 tree with X Coordinates 3,3,1,3,4. Then their ranks may be 2,2,1,2,5. The FAR of two trees with X Coordinate ranks D1 and D2 is defined as F = abs(D1-D2).

The SHORT is defined similar to the FAR. If we rank all these trees according to their heights in ascending order,the tree with shortest height is ranked 1th.The trees with the same heights are ranked the same. For example, if there are 5 tree with heights 4,1,9,7,4. Then their ranks may be 2,1,5,4,2. The SHORT of two trees with height ranks H1 and H2 is defined as S=min(H1,H2).

Two tree’s Disharmony Value is defined as F*S. So from the definition above we can see that, if two trees’s FAR is larger , the Disharmony Value is bigger. And the Disharmony value is also associated with the shorter one of the two trees. 

Now give you every tree’s X Coordinate and their height , Please tell Sophia the sum of every two trees’s Disharmony value among all trees.

Input

There are several test cases in the input

For each test case, the first line contain one integer N (2 <= N <= 100,000) N represents the number of trees.

Then following N lines, each line contain two integers : X, H (0 < X,H <=1,000,000,000 ), indicating the tree is located in Coordinates X and its height is H.

Output

For each test case output the sum of every two trees’s Disharmony value among all trees. The answer is within signed 64-bit integer.

Sample

Inputcopy Outputcopy
 
2 
10 100 
20 200 
4 
10 100
50 500
20 200 
20 100 
 
1 
13

翻译:

        FAR的定义如下:如果我们根据这些树的X坐标从大到小进行排序,X坐标最小的树排在第1位,X坐标相同的树排在一起。例如,如果有5棵X坐标为3、3、1、3、4的树。那么他们的等级可能是2,2,1,2,5。X坐标等级为D1和D2的两棵树的FAR被定义为F=abs(D1-D2)。

SHORT的定义与FAR相似。如果我们根据这些树的高度从高到低排序,高度最短的树排在第1位,高度相同的树排在一起。例如,如果有5棵树,高度为4,1,9,7,4。那么他们的排名可能是2,1,5,4,2。高度为H1和H2的两棵树的SHORT被定义为S=min(H1,H2)。

两棵树的不和谐值被定义为F*S。因此,从上面的定义我们可以看出,如果两棵树的FAR越大,Disharmony值就越大。而且不和谐值也与两棵树中较短的那棵有关。

现在给你每棵树的X坐标和它们的高度,请告诉Sophia所有树中每两棵树的不和谐值之和。

题目大意:

        将树按照x坐标和高度分别从大到小排序。小的F从1开始,如果俩颗树的x坐标相同,那么等级相同。类似于x坐标为3,1,3,3,5 。那么他的F就是2,1,2,2,5.高度S同样如此排序,然后求俩俩之间F*S的和:v=min(h1,h2)*abs(x1,x2)

#include
#include
#include
#include
#include
#include
#include
//#include
#include
#include
//#include 
#include
#include
#include
#define dbug cout<<"hear!"<=c;a--)
#define no cout<<"NO"<,greater >q;
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair PII;
typedef pair PDD;
const int N = 1e5 + 5;
const int  INF = 0x3f3f3f3f;
//const ll LINF=LLONG_MAX;
// ll gcdd(ll a, ll b)
// {
//       while(b^=a^=b^=a%=b);    
//       return a;
// }
// void add(ll a,ll w)
// {
//   noda[++idx].b=w;
//   noda[idx].ne=h[a];
//   h[a]=idx;
// }
ll h[N],idx;
const ll mod =1000000007;
ll  t, n,a,b,c,d, m, x,y, k, cnt, ans, ant, sum,q,p,num;
ll arr[N],brr[N], crr[N];
ll book[N];
struct node
{
  ll x,h;
  ll xx,hh;
}noda[N];
bool cmpx(node a,node b)
{
  return a.xb.hh;
}
ll lowbit(ll x)
{
  return x&(-x);
}
void update(ll c[],ll x,ll w)
{
  for(ll i=x;i<=num+1;i+=lowbit(i))c[i]+=w;
}
ll getsum(ll c[],ll x)
{
  sum=0;
  for(ll i=x;i;i-=lowbit(i))sum+=c[i];
  return sum;
}
int main()
{
  IOS;
  while(cin>>n)
  {
    num=0;
    rep(i,1,n)
    {
      cin>>noda[i].x>>noda[i].h;
      arr[i]=brr[i]=0;
    }
    sort(noda+1,noda+1+n,cmpx);//按照x坐标进行排序
    noda[1].xx=1;//第一个位置离散化为1;
    rep(i,2,n)
    {
      if(noda[i].x==noda[i-1].x)
      {
        noda[i].xx=noda[i-1].xx;//如果相同那么,其等级是一样的
        num++;
      }else 
      {
        noda[i].xx=i;//如果不相同,那么按照题目意思是不去重重的离散化,所以直接变成i;
        num++;
      }
    }
    sort(noda+1,noda+1+n,cmph);//按照h排序;
    noda[1].hh=1;
    rep(i,2,n)
    {
      if(noda[i].h==noda[i-1].h)
      {
        noda[i].hh=noda[i-1].hh;
      }else{
        noda[i].hh=i;
      }
    }
    sort(noda+1,noda+1+n,cmphh);//按照hh再进行一次排序这样就可以避免用min函数;
    ans=0;
    rep(i,1,n)
    {
      a=getsum(arr,noda[i].xx);//得到xx之前的个数
      b=getsum(brr,noda[i].xx);//得到xx之前的个数和
       cnt=getsum(brr,n);//得到综合,算区间
      ans+=noda[i].hh*((a*noda[i].xx -b)+(cnt-b)-(i-a-1)*noda[i].xx);//这样计算可以规避出现负数情况。
      update(arr,noda[i].xx,1);
      update(brr,noda[i].xx,noda[i].xx);
    }
    cout<

 

你可能感兴趣的:(算法,c++,开发语言)