上帝造题的七分钟
Background
裸体就意味着身体。
Description
“第一分钟,X说,要有矩阵,于是便有了一个里面写满了
0
的
第二分钟,L说,要能修改,于是便有了将左上角为
(a,b)
,右下角为
(c,d)
的一个矩形区域内的全部数字加上一个值的操作。
第三分钟,k说,要能查询,于是便有了求给定矩形区域内的全部数字和的操作。
第四分钟,彩虹喵说,要基于二叉树的数据结构,于是便有了数据范围。
第五分钟,和雪说,要有耐心,于是便有了时间限制。
第六分钟,吃钢琴男说,要省点事,于是便有了保证运算过程中及最终结果均不超过32位有符号整数类型的表示范围的限制。
第七分钟,这道题终于造完了,然而,造题的神牛们再也不想写这道题的程序了。”
——《上帝造裸题的七分钟》
所以这个神圣的任务就交给你了。
Input
输入数据的第一行为
X n m
,代表矩阵大小为
n×m
。
从输入数据的第二行开始到文件尾的每一行会出现以下两种操作:
L a b c d delta
—— 代表将
(a,b)
,
(c,d)
为顶点的矩形区域内的所有数字加上
delta
。
k a b c d
—— 代表求
(a,b)
,
(c,d)
为顶点的矩形区域内所有数字的和。
请注意, k 为小写。
Output
针对每个
Sample Input
X 4 4
L 1 1 3 3 2
L 2 2 4 4 1
k 2 2 3 3
Sample Output
12
Hint
对于
10%
的数据,
1≤n≤16
,
1≤m≤16
, 操作不超过
200
个.
对于
60%
的数据,
1≤n≤512
,
1≤m≤512
.
对于
100%
的数据,
1≤n≤2048
,
1≤m≤2048
,
1≤delta≤500
, 操作不超过
200000
个,保证运算过程中及最终结果均不超过32位带符号整数类型的表示范围。
by XLk
Solution
二维树状数组,区间修改+区间查询模板题。
学到了神犇Cai的读入优化,感觉大神的代码就是不同,读入优化都比我快。
Code
#include <iostream>
#include <cstdio>
using namespace std;
int n,m,num,ch[100];
char str;
int bit1[2059][2059];
int bit2[2059][2059];
int bit3[2059][2059];
int bit4[2059][2059];
inline void in(int &ans){
ans=0;
int flag=1;
char x=getchar();
while((x<'0'||x>'9')&&x!='-')x=getchar();
if(x=='-'){flag=-1;x=getchar();}
while(x>='0'&&x<='9'){ans=ans*10+x-'0';x=getchar();}
ans*=flag;
}
inline void add(int x,int y,int z,int array[2059][2059]){
for(int i=x;i<=n;i+=(i&-i))
for(int j=y;j<=m;j+=(j&-j))
array[i][j]+=z;
}
inline int get_sum(int x,int y,int array[2059][2059]){
int tmp=0;
for(int i=x;i;i-=(i&-i))
for(int j=y;j;j-=(j&-j))
tmp+=array[i][j];
return tmp;
}
inline int sum(int x,int y){
int tmp=0;
tmp+=get_sum(x,y,bit1)*x*y;
tmp-=get_sum(x,y,bit2)*x;
tmp-=get_sum(x,y,bit3)*y;
tmp+=get_sum(x,y,bit4);
return tmp;
}
inline void out(int k){
if(k<0){putchar('-');k=-k;}
if(k==0){putchar('0');putchar(10);return;}
while(k>0)ch[++num]=k%10,k/=10;
while(num)putchar(ch[num--]+48);
putchar(10);
}
int main(){
getchar();getchar();in(n);in(m);
while((str=getchar())!=-1){
if(str=='L'){
int a,b,c,d,delta;
in(a);in(b);in(c);in(d);in(delta);
add(a,b,delta,bit1);add(a,d+1,-delta,bit1);
add(c+1,b,-delta,bit1);add(c+1,d+1,delta,bit1);
add(a,b,delta*(b-1),bit2);add(a,d+1,-delta*(d),bit2);
add(c+1,b,-delta*(b-1),bit2);add(c+1,d+1,delta*(d),bit2);
add(a,b,delta*(a-1),bit3);add(a,d+1,-delta*(a-1),bit3);
add(c+1,b,-delta*(c),bit3);add(c+1,d+1,delta*(c),bit3);
add(a,b,delta*(a-1)*(b-1),bit4);add(a,d+1,-delta*(a-1)*(d),bit4);
add(c+1,b,-delta*(c)*(b-1),bit4);add(c+1,d+1,delta*(c)*(d),bit4);
}
else{
int a,b,c,d;
in(a);in(b);in(c);in(d);
out(sum(c,d)+sum(a-1,b-1)-sum(c,b-1)-sum(a-1,d));
}
}
return 0;
}