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

原创 2015年07月11日 09:03:52

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




版权声明:转吧。

POJ 1990 MooFest(想法题&树状数组)

MooFest http://poj.org/problem?id=1990 Time Limit: 1000MS Memory Limit: 30000K Description Every ...
  • synapse7
  • synapse7
  • 2013年08月01日 22:35
  • 1320

树状数组题集[不断更新]

一. 基本原理 树状数组中用的d【】,每个点都有一定的管辖范围; 如c[1]=a[1]; d[2]=a[1]+a[2]; d[3]=a[3]; d[4]=a[1]...
  • Matrix_Reloaded
  • Matrix_Reloaded
  • 2014年06月18日 11:40
  • 2998

梅克尔树Merkle trees是什么?(以太坊)

梅克尔树(Merkle trees)是区块链的基本组成部分。虽说从理论上来讲,没有梅克尔树的区块链当然也是可能的,你只需创建直接包含每一笔交易的巨大区块头(block header)就可以实现,但这样...
  • fidelhl
  • fidelhl
  • 2016年01月14日 21:32
  • 5007

hdu3015 Disharmony Trees(树状数组)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3015 题意:在路边有一行树,给出它们的坐标和高度,先按X坐标排序。记录排名,记为rankx,再按它们...
  • fire__ice
  • fire__ice
  • 2012年09月30日 17:38
  • 483

hdu 3015 Disharmony Trees(树状数组)

Disharmony TreesProblem DescriptionOne day Sophia finds a very big square. There are n trees in the ...
  • blessLZH0108
  • blessLZH0108
  • 2017年06月05日 20:30
  • 218

HDU 3015 Disharmony Trees 树状数组

来源:http://acm.hdu.edu.cn/showproblem.php?pid=3015 题意:有一些树,这些树的高度和位置给出。现在高度和位置都按从小到大排序,对应一个新的rank,任意...
  • wmn_wmn
  • wmn_wmn
  • 2012年09月29日 21:38
  • 1122

poj 1990 MooFest(树状数组)

题意:N头奶牛每头耳背程度v,坐标x。两牛交流需要音量为distance * max(v(i),v(j)),求 所有牛两两交流所需总和? 思路:对耳背进行升序,一头一头的加入牛,这样加入每...
  • CillyB
  • CillyB
  • 2016年10月19日 23:59
  • 156

POJ 1990 MooFest(树状数组+离线处理)

POJ1990 MooFest(树状数组+离线处理) 分析: 因为要求max(vi,vj),所以先读入所有的牛,将牛按它的vi值从小到大排序,所以当前处理的牛总是vi值最大的。 接下来就要算当前第i头...
  • u013480600
  • u013480600
  • 2014年03月20日 21:20
  • 715

poj 1990 MooFest(树状数组)

题目链接:http://poj.org/problem?id=1990 思路: 树状数组 分析: 1 题目给定n头牛的听力v[i]. 现在规定两头你i和j如果要进行交流的话那么消耗的能量就是...
  • qq_36782366
  • qq_36782366
  • 2017年07月20日 10:37
  • 58

POJ 1990 MooFest(树状数组)

http://poj.org/problem?id=1990 题意:一群奶牛排在一根坐标轴上,并且知道奶牛的位置,每个奶牛都有一个对话时候能够听到的最小音量。每两个奶牛对话的时候,所需要的音...
  • secfly
  • secfly
  • 2016年03月13日 21:24
  • 368
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:poj1990 MooFest && hdu3015 Disharmony Trees (树状数组)
举报原因:
原因补充:

(最多只允许输入30个字)