HDOJ 1556 Color the ball

http://acm.hdu.edu.cn/showproblem.php?pid=1556

樹狀數組解法:

題意:給N段連續的球上色,求上色後每個球被塗色的次數。

思路:假設有一個數組d,令其的初值爲0。若塗色 [ L,R ] 的區間,則令d [ L ] +=1;d [R] - =1;C [ i ] 爲對應數組d的前i項和,這樣C是 [ L,R ] 的區間就記錄了球的塗色次數。因爲實際操作時d數組用不到,故可以略去。通過這個技巧就將斷更新轉化爲了點更新,求第i個球塗幾次只需求d的先i項和(即C [ i ] )即可。這樣就變成一個簡單的樹狀數組求和問題了~

關於C數組和d數組的關係舉個例子吧:

第一次塗 [ L,R ] 區間:

下標 1    2    3    4    5    6    7    8    9    ……

C   :  0    0    1    1    1    1    0    0    0    ……

d   :  0    0    1    0    0    0   -1    0    0    ……

                      L                R   R+1

#include<stdio.h>
#include<string.h>

#define maxn 111111

int n,C[maxn];

int Lowbit(int x)
{
	return x&(-x);
}

void updata(int i,int x)
{
	while(i<=n)
	{
		C[i]+=x;
		i+=Lowbit(i);
	}
}

int sum(int end)
{
	int sum=0;
	while(end>0)
	{
		sum+=C[end];
		end-=Lowbit(end);
	}
	return sum;
}
int main()
{
	while(scanf("%d",&n)&&n)
	{
		int i,m=n;
		memset(C,0,sizeof(C));
		while(m--)
		{
			int a,b;
			scanf("%d %d",&a,&b);
			updata(a,1);
			updata(b+1,-1);
		}
		printf("%d",sum(1));
		for(i=2;i<=n;i++)
			printf(" %d",sum(i));
		printf("\n");
	}
	return 0;
}
線段樹解法:用線段樹做就很簡單啦~(代碼有時間再補一下啦)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章