hdu 1166 樹狀數組 線段樹

一道線段樹和樹狀數組的基礎題

用樹狀數組做:

#include<iostream>
using namespace std;
#define N 50010
int size,c[N];
int lowbit(int x)
{
	return x&(-x);
}
void modify(int i,int x)
{
	while(i <= size)
	{
		c[i] += x;
		i += lowbit(i);
	}
}
int sum(int i)
{
	int ans = 0;
	while(i > 0)
	{
		ans += c[i];
		i -= lowbit(i);
	}
	return ans;
}
int main()
{
	int t,total = 1;
	scanf("%d",&t);
	char str[10];
	while(t--)
	{
		memset(c,0,sizeof(c));  //每次輸入一組新的數據之前都要把數組c 置0
		scanf("%d",&size);
		int a,b,c,i;
		for(i = 1;i <= size;i++)
		{
			scanf("%d",&c);
			modify(i,c);
		}
		printf("Case %d:\n",total++);
		while(scanf("%s",str)&&str[0] != 'E')
			{
				scanf("%d%d",&a,&b);
				switch(str[0])
				{
		          case 'Q': printf("%d\n",sum(b) - sum(a-1));
					  break;
			      case 'A':  modify(a,b);
					  break;
				  case 'S': modify(a,-b);
					  break;
				}
				
			}
	}
	return 0;
}

用線段樹做:

#include<iostream>
using namespace std;
#define N 50010
struct node
{
	int left,right;
	int sum;
}tree[N*4];
int num[N];
void build(int l,int r,int i)
{
	tree[i].left = l;
	tree[i].right = r;
	if(l == r)
	{
		tree[i].sum = num[l];
		return ;
	}
	int mid = (l+r)>>1;
	build(l,mid,i*2);
	build(mid+1,r,i*2+1);
	tree[i].sum = tree[i*2].sum + tree[i*2+1].sum;
}
void modify(int l,int r,int v,int i)
{
	if(tree[i].left == l&&tree[i].right == r)
	{
		tree[i].sum += v;
		return ;
	}
	int mid = (tree[i].left + tree[i].right)>>1;
	if(r <= mid)
		modify(l,r,v,i*2);
	else if(l > mid)
		modify(l,r,v,i*2+1);
	else 
	{
		modify(l,mid,v,i*2);
		modify(mid+1,r,v,i*2+1);
	}
	tree[i].sum = tree[i*2].sum + tree[i*2+1].sum;
}
int query(int l,int r,int i)
{
	if(l == tree[i].left&&r == tree[i].right)
		return tree[i].sum;
	int mid = (tree[i].left + tree[i].right)>>1;
	if(r <= mid)
		return query(l,r,i*2);
	else if(l > mid)
		return query(l,r,i*2+1);
	else
		return query(l,mid,i*2) + query(mid+1,r,i*2+1);
}

int main()
{
	int t,total = 1;
	scanf("%d",&t);
	while(t--)
	{
		int n;
		char str[20];
		scanf("%d",&n);
		int i,a,b;
		for(i = 1;i <= n;i++)
			scanf("%d",num+i);
		build(1,n,1);
		printf("Case %d:\n",total++);
		while(scanf("%s",str)&&str[0] != 'E')
		{
			scanf("%d%d",&a,&b); 
			//不用加 getchar() 如果str 是字符則需要 字符串不需要
			switch(str[0])
			{
		          case 'Q': printf("%d\n",query(a,b,1));
					  break;
			      case 'A':  modify(a,a,b,1);
					  break;
				  case 'S': modify(a,a,-b,1);
					  break;
			}
		}
	}
	return 0;
}


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