题目:http://poj.org/problem?id=1990 && http://acm.hdu.edu.cn/showproblem.php?pid=3015
题意:这两题题目意思差不多,只说下poj1990的。告诉每只牛的位置xi以及耳聋程度vi,和两只牛进行交流需要的音量s=abs(xi-xj)*max(vi,vj),求每头牛两两(n*(n-1)/2)交流需要的总音量。
分析:对于任意一头牛Ci找比它耳聋程度低的牛,那么再找到每头牛到xi的距离的和S就行了。S=比xi大的位置的和-比xi大的位置的个数*xi+比xi小的位置的个数*xi-比xi小的位置的和。算个数以及位置的和,分别用两个树状数组统计就行了。
poj1990代码:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int maxn = 20048;
int lowbit[maxn],tree[maxn],cnt[maxn];
struct node
{
int v;
int pos;
bool operator < (const node &t) const
{
return v<t.v;
}
}s[maxn];
void CalLowbit()
{
for(int i=1;i<maxn;i++)
lowbit[i]=(i&-i);
}
void update(int x,int v)
{
for(int i=x;i<maxn;i+=lowbit[i])
tree[i]+=v;
}
int query(int x)
{
int ret(0);
for(int i=x;i>0;i-=lowbit[i])
ret+=tree[i];
return ret;
}
void Cupdate(int x,int v)
{
for(int i=x;i<maxn;i+=lowbit[i])
cnt[i]+=v;
}
int Cquery(int x)
{
int ret(0);
for(int i=x;i>0;i-=lowbit[i])
ret+=cnt[i];
return ret;
}
int main()
{
CalLowbit();
int n,i,j,c;
long long Less,More,Sum,ans;
while(scanf("%d",&n)!=EOF)
{
memset(cnt,0,sizeof(cnt));
memset(tree,0,sizeof(tree));
for(i=0;i<n;i++)
scanf("%d%d",&s[i].v,&s[i].pos);
sort(s,s+n);
ans=Sum=0;
for(i=0;i<n;i++)
{
Less=query(s[i].pos);
c=Cquery(s[i].pos);
ans+=s[i].v*(c*s[i].pos-Less+(Sum-Less)-(i-c)*s[i].pos);
update(s[i].pos,s[i].pos);
Cupdate(s[i].pos,1);
Sum+=s[i].pos;
}
printf("%lld\n",ans);
}
return 0;
}
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int maxn = 100009;
int tree[maxn],cnt[maxn],lowbit[maxn],buf[maxn];
struct node
{
int X,H;
bool operator < (const node &t) const
{
return H>t.H;
}
}s[maxn];
bool cmp1(node a,node b)
{
return a.H<b.H;
}
bool cmp2(node a,node b)
{
return a.X<b.X;
}
void Pre(int n)
{
memset(tree,0,sizeof(tree[0])*(n+3));
memset(cnt,0,sizeof(cnt[0])*(n+3));
buf[0]=1;
sort(s,s+n,cmp1);
for(int i=1;i<n;i++)
{
if(s[i].H==s[i-1].H)
buf[i]=buf[i-1];
else
buf[i]=i+1;
}
for(int i=0;i<n;i++)
s[i].H=buf[i];
sort(s,s+n,cmp2);
for(int i=1;i<n;i++)
{
if(s[i].X==s[i-1].X)
buf[i]=buf[i-1];
else
buf[i]=i+1;
}
for(int i=0;i<n;i++)
s[i].X=buf[i];
sort(s,s+n);
}
void CalLowbit()
{
for(int i=1;i<maxn;i++)
lowbit[i]=i&-i;
}
void update(int x,int v)
{
for(int i=x;i<maxn;i+=lowbit[i])
tree[i]+=v;
}
int query(int x)
{
int ret(0);
for(int i=x;i>0;i-=lowbit[i])
ret+=tree[i];
return ret;
}
void Cupdate(int x,int v)
{
for(int i=x;i<maxn;i+=lowbit[i])
cnt[i]+=v;
}
int Cquery(int x)
{
int ret(0);
for(int i=x;i>0;i-=lowbit[i])
ret+=cnt[i];
return ret;
}
int main()
{
CalLowbit();
int n,i,j,k,c;
long long ans,Less,Sum;
while(scanf("%d",&n)!=EOF)
{
for(i=0;i<n;i++)
scanf("%d%d",&s[i].X,&s[i].H);
Pre(n);
Sum=ans=0;
for(i=0;i<n;i++)
{
Less=query(s[i].X);
c=Cquery(s[i].X);
ans+=s[i].H*(c*s[i].X-Less+Sum-Less-s[i].X*(i-c));
Sum+=s[i].X;
update(s[i].X,s[i].X);
Cupdate(s[i].X,1);
}
printf("%lld\n",ans);
}
return 0;
}