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; }
朋友们,虽然这个世界日益浮躁起来,只要能够为了当时纯粹的梦想和感动坚持努力下去,不管其它人怎么样,我们也能够保持自己的本色走下去。