P1294 - 【IOI 2001 】移动电话
Description
假设Tampere地区的4G移动通信基站以如下方式运行。整个地区被划分成若干正方形格子。这些格子构成一个S * S的矩阵,它们的行,列编号都是从0到S-1.每一个格子中都有一个基站。每个格子中激活的手机数量可能改变,因为一部手机可能从一个格子移动到另一个格子,打开或者关闭。有时,某一座基站会向总站报告自己的行列坐标,以及该格中激活手机数目的变化。
Input
输入指令编码如下。
每个指令占一行,包含一个指令码和一些参数,见下表。
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
矩阵大小:1<=S<=1024
任意时刻,每个格子中的激活手机数量V:0<=V<=32767
格子中激活手机数量的变化值:-32768<=A<=32767
输入的指令数目:3<=U<=60002
整个矩阵中的最大手机数量:M=2^30
Source
IOI 2001
树状数组,线段树
二维树状数组裸题
1 #define ll long long 2 #define ls o<<1 3 #define rs (o<<1)|1 4 #define mimi int mid=(L+R)>>1; 5 #define rep(i,a,b) for(register int i=a;i<=b;i++) 6 #include<algorithm> 7 #include<iostream> 8 #include<iomanip> 9 #include<cstring> 10 #include<cstdlib> 11 #include<cstdio> 12 #include<queue> 13 #include<ctime> 14 #include<cmath> 15 #include<stack> 16 #include<map> 17 #include<set> 18 #define il inline 19 using namespace std; 20 const int N=1024+10; 21 int C[N][N],S; 22 int gi(); 23 int lowbit(int x) {return x & (-x);} 24 il void add(int x,int y,int c) { 25 int t=y; 26 while(x<=S) { 27 while(y<=S) C[x][y] +=c,y+=lowbit(y); 28 y=t; 29 x+=lowbit(x); 30 } 31 } 32 il int getsum(int x,int y) { 33 int sum=0; 34 int t=y; 35 while(x) { 36 while(y) sum+=C[x][y],y-=lowbit(y); 37 y=t; 38 x-=lowbit(x); 39 } 40 return sum; 41 } 42 int main() { 43 int k=gi(); 44 S=gi(); 45 while(1) { 46 k=gi();int x,y,L,B,R,T,A; 47 if(k==1) x=gi(),y=gi(),A=gi(),x++,y++,add(x,y,A); 48 else if(k==2) L=gi()+1,B=gi()+1,R=gi()+1,T=gi()+1,printf("%d\n",getsum(R,T)-getsum(L-1,T)-getsum(R,B-1)+getsum(L-1,B-1)); 49 else break; 50 } 51 } 52 il int gi() { 53 int res=0,f=1; 54 char ch=getchar(); 55 while((ch<'0'||ch>'9')&&ch!='-') ch=getchar(); 56 if(ch=='-') ch=getchar(),f=-1; 57 while(ch>='0'&&ch<='9') res=res*10+ch-'0',ch=getchar(); 58 return res*f; 59 }