hdu 4000 Fruit Ninja, hdu 4020 Ads Proposal

两道树状数组题。

推荐一篇介绍树状数组比较好的博客:http://www.cnblogs.com/yykkciwei/archive/2009/05/08/1452889.html

hdu 4000 Fruit Ninja

题目来源:http://acm.hdu.edu.cn/showproblem.php?pid=4000

思路:对每个位置处理,考虑后面有多少比他大的数,则该位置上的数与后面两个大数可构成x*(x-1)/2种,再把所有的i<j<k && a[i]<a[j]<a[k]除去。

code:

# include<stdio.h>

# include<string.h>

# define Mod 100000007

int count[100005],n;

__int64 ans;

void insert(int i)

{

	while(i<=n)

	{

		count[i]++;

		i+= i&(-i);

	}

}

int query(int i)

{

	int num=0;

	while(i>0)

	{

		num+=count[i];

		i-=i&(-i);

	}

	return num;

}

int main()

{

	int i,ncase,t,a;

	__int64 tmp1,tmp2;

	scanf("%d",&ncase);

	for(t=1;t<=ncase;t++)

	{

		scanf("%d",&n);

		memset(count,0,sizeof(count));

		ans=0;

		for(i=1;i<=n;i++)

		{

			scanf("%d",&a);

			insert(a);

			tmp1=query(a-1);//扫描比a小的数

			tmp2=n-a-(i-tmp1-1);//在a后面比a大的数

			ans-=tmp1*tmp2;//除去i<j<k && a[i]<a[j]<a[k]的情况

			if(tmp2>=2) ans+=tmp2*(tmp2-1)/2;

		}

		printf("Case #%d: %d\n",t,ans%Mod);

	}

	return 0;

}

 

hdu  4020 Ads Proposal

题目来源:http://acm.hdu.edu.cn/showproblem.php?pid=4020

可以用模拟预处理,感觉时间复杂度也不是很高,虽然AC了但4000+ms,估计数据量特别大。

此题也是树状数组。先把所有的广告根据点击次数从大到小进行排序,然后每处理一条广告,判断该条广告是这个人的第几天广告,然后把该条广告的长度作为增量增加到一个数组上!

code:

# include<stdio.h>

# include<string.h>

# include<stdlib.h>

# define M 500005

__int64 sum[M];

int m,visit[100005];

struct node{

    int id,c,len;

}s[M];

int Lowbit(int i)

{

    return i&(-i);

}

void puls(int i,int num)

{

    while(i<=m)

    {

        sum[i]+=num;

        i+=Lowbit(i);

    }

}

__int64 getsum(int i)

{

    __int64 ans=0;

    while(i>0)

    {

        ans+=sum[i];

        i-=Lowbit(i);

    }

    return ans;

}

int cmp(const void *a,const void *b)

{

    struct node *c=(struct node *)a;

    struct node *d=(struct node *)b;

    return d->c - c->c;

}

int main()

{

    int i,n,Q,ncase,t,k;

    scanf("%d",&ncase);

    for(t=1;t<=ncase;t++)

    {

        scanf("%d%d%d",&n,&m,&Q);

        for(i=1;i<=m;i++)

            scanf("%d%d%d",&s[i].id,&s[i].c,&s[i].len);

        qsort(s+1,m,sizeof(s[1]),cmp);

        memset(visit,0,sizeof(visit));

        memset(sum,0,sizeof(sum));

        for(i=1;i<=m;i++)

        {

            visit[s[i].id]++;

            puls(visit[s[i].id],s[i].len);

        }

        printf("Case #%d:\n",t);

        while(Q--)

        {

            scanf("%d",&k);

            if(k>m) k=m;

            printf("%I64d\n",getsum(k));

        }

    }

    return 0;

}

感觉写的也没错啊。。不过交了之后仍然4000ms+,很是无语~~

你可能感兴趣的:(HDU)