poj1990(树状数组)
题意:FJ有n头牛,排列成一条直线(不会在同一个点),给出每头牛在直线上的坐标x。另外,每头牛还有一个自己的声调v,如果两头牛(i和j)之间想要沟通的话,它们必须用同个音调max(v[i],v[j]),沟通起来消耗的能量为:max(v[i],v[j]) * 它们之间的距离。问要使所有的牛之间都能沟通(两两之间),总共需要消耗多少能量。
思路:此题和hdu3015(我前面写的,有详细解答)一种类型的,传送门:http://www.cnblogs.com/ziyi--caolu/archive/2012/12/30/2839892.html
#include<iostream>
#include<algorithm>
using namespace std;
struct node
{
int h,d;
}s[20005];
int cmp(node &a,node &b)
{
if(a.h>b.h)
return 1;
else
return 0;
}
int c[20005],d[20005],n;
int lowbit(int x)
{
return x&(-x);
}
void updatac(int i,int j)
{
while(i<=20000)
{
c[i]+=j;
i+=lowbit(i);
}
}
__int64 getsumc(int x)
{
__int64 sum=0;
while(x>0)
{
sum+=c[x];
x-=lowbit(x);
}
return sum;
}
void updatad(int i,int j)
{
while(i<=20000)
{
d[i]+=j;
i+=lowbit(i);
}
}
int getsumd(int x)
{
int sum=0;
while(x>0)
{
sum+=d[x];
x-=lowbit(x);
}
return sum;
}
int main()
{
while(scanf("%d",&n)>0)
{
int i;
memset(c,0,sizeof(c));
memset(d,0,sizeof(d));
int max=0;
for(i=1;i<=n;i++)
{
scanf("%d %d",&s[i].h,&s[i].d);
if(s[i].d>max)
max=s[i].d;
}
//printf("%d\n",max);
sort(s+1,s+1+n,cmp);
for(i=1;i<=n;i++)
{
updatac(s[i].d,s[i].d);
updatad(s[i].d,1);
//printf("%d %d\n",s[i].h,s[i].d);
}
__int64 sum=0,tmp1,tmp2,m=n;
for(i=1;i<=n;i++)
{
tmp1=getsumd(s[i].d-1)*s[i].d-getsumc(s[i].d-1);
tmp2=(getsumd(max)-getsumd(s[i].d))*s[i].d-(getsumc(max)-getsumc(s[i].d));
sum+=(tmp1-tmp2)*s[i].h;
//printf("%I64d\t %I64d\t %I64d\t %I64d\t %I64d\n",getsumc(max),getsumc(s[i].d),getsumd(max),getsumd(s[i].d),sum);
updatac(s[i].d,-s[i].d);
updatad(s[i].d,-1);
}
printf("%I64d\n",sum);
}
return 0;
}
朋友们,虽然这个世界日益浮躁起来,只要能够为了当时纯粹的梦想和感动坚持努力下去,不管其它人怎么样,我们也能够保持自己的本色走下去。

浙公网安备 33010602011771号