关闭

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

标签: 树状数组离散化
200人阅读 评论(0) 收藏 举报
分类:

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

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:69519次
    • 积分:2643
    • 等级:
    • 排名:第13822名
    • 原创:201篇
    • 转载:2篇
    • 译文:0篇
    • 评论:5条
    最新评论