移动电话(二维树状数组)

Description
假设第四代移动电话的收发站是这样工作的。整个区域被分割成很小的方格。所有的方格组成了一个SS的矩阵,行和列都是从0~S-1编号。每个小方格都包含一个收发站。每个方格内的开机的移动电话数量可以不断改变,因为手机用户在各个方格之间移动,也有用户开机或关机。一旦某个方格里面开机的移动电话数量发生了变化,该方格里收发站就会向总部发送一条信息说明这个改变量。
老板可能随时会问:某个给定矩形区域内有多少部开机的移动电话呀?要求你编写一个程序能随时回答老板的问题。
Input
输入数据的格式如下:
0 S:表示初始命令,整个区域由S
S个小格子组成指令只会在一开始出现一次。
1 X Y A:方格(X,Y)内的开机移动电话量增加了A。A可能是正数也可能是负数。
2 L B R T:询问在矩形区域(L,B)到(R,T)内有多少部开机的移动电话。
3:表示终止程序,这个指示只会在最后出现一次。
Output
对于除了2之外的提示,你的程序不应该输出任何东西。如果指示是2,那么你程序应该向输出一个整数。
Sample Input
0 4
1 1 2 3
2 0 0 2 2
1 1 1 2
1 1 2 -1
2 1 1 2 3
3
Sample Output
3
4
Hint
100%的数据:S≤1024。

这题是二维树状数组的模板吧
code

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int n,c[1050][1050];
void Add(int x,int y,int k)
{  int i,j;
   for(i=x;i<=n;i+=i&(-i))
       for(j=y;j<=n;j+=j&(-j))c[i][j]+=k;
}
int Sum(int x,int y)//求到第i行,第j列的前缀和 
{  
	int i,j,s=0;
   	for(i=x;i>0;i-=i&(-i))
       for(j=y;j>0;j-=j&(-j))
	   	s+=c[i][j];
   return s;
}
int calc(int x1,int y1,int x2,int y2)//求(x1,y1)到(x2,y2) 
{ 
	return Sum(x2,y2)-Sum(x1-1,y2)-Sum(x2,y1-1)+Sum(x1-1,y1-1);
}
int main()
{  
	int t,i,j,x1,y1,x2,y2,k;
   	while(1)
   	{  
   		scanf("%d",&t);
      	if(t==0)
      	{  
	  		scanf("%d",&n);
         	for(i=1;i<=n;i++)
             	for(j=1;j<=n;j++)
			 		c[i][j]=0;
      	}
      	if(t==1)
      	{
		  	scanf("%d%d%d",&x1,&y1,&k);
         	x1++;y1++;
         	Add(x1,y1,k);
      	}
      	if(t==2)
		{  
	  		scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
            x1++;y1++;x2++;y2++;
            printf("%d\n",calc(x1,y1,x2,y2));
    	}
      	if(t==3)
		  	break;
   	}
   	return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值