poj1990 MooFest && hdu3015 Disharmony Trees (树状数组)

来源:互联网 发布:ubuntu wine中文乱码 编辑:程序博客网 时间:2024/05/16 01:30

题目: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;}


对于hdu3015,先对D和H重新编号。后面的和poj1990差不多了。


#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;}


0 0
原创粉丝点击