「codecomb2097」rect
Description
在一个n*m的格子棋盘上,有n*m堆石子,现在有两种操作:
1、给(x1,y1)->(x2,y2)这个矩形内所有的石子堆加入k个石子。1<=x1<=x2<=n,1<=y1<=y2<=m。
2、询问某格(x,y)上面有多少石子。
Input
第一行两个整数n和m,分别表示棋盘的长宽,n对应上述的x轴,m对应y轴。
第二行一个整数p,表示操作数量。
以下p行,首先一个是整数t,t=1或2,表示是哪种操作。 如果t=1,则后面跟5个整数x1,y1,x2,y2,k,如上所述。如果t=2,后面跟两个整数x,y,表示上述询问操作。
Output
对于每一个询问,输出石子数量。
Sample Input
3 3
2
1 1 1 2 2 1
2 1 1
Sample Output
1
Hint
数据范围:
40%的数据n,m<=1000
100%的数据n*m<1000000,p<=50000
答案保证在longint范围内
题解
二维树状数组。。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
#include<iostream> #include<cstdio> #include<cstdlib> #include<algorithm> #include<cmath> #include<cstring> #define inf 1000000000 #define ll long long using namespace std; int read() { int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } int n,m,p; int t[1500005]; inline int get(int x,int y) { return (x-1)*m+y; } void add(int x,int y,int val) { for(int i=x;i<=n;i+=i&(-i)) for(int j=y;j<=m;j+=j&(-j)) t[get(i,j)]+=val; } int query(int x,int y) { int sum=0; for(int i=x;i;i-=i&(-i)) for(int j=y;j;j-=j&(-j)) sum+=t[get(i,j)]; return sum; } int main() { n=read();m=read(); int t,x1,y1,x2,y2,K; p=read(); for(int i=1;i<=p;i++) { t=read(); if(t==1) { x1=read();y1=read();x2=read();y2=read();K=read(); add(x2+1,y2+1,K); add(x2+1,y1,-K); add(x1,y2+1,-K); add(x1,y1,K); } else { x1=read();y1=read(); printf("%d\n",query(x1,y1)); } } return 0; } |
Subscribe