【樹狀數組】BZOJ3132 上帝造題的七分鐘
阿新 • • 發佈:2017-12-08
-s 文件 輸入 二叉 ios pan 鋼琴 數據結構 頂點
Submit: 1004 Solved: 445
[Submit][Status][Discuss]
L 1 1 3 3 2
L 2 2 4 4 1
k 2 2 3 3
、v[i][j]*i*j 的前綴和
3132: 上帝造題的七分鐘
Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 1004 Solved: 445
[Submit][Status][Discuss]
Description
“第一分鐘,X說,要有矩陣,於是便有了一個裏面寫滿了0的n×m矩陣。
第二分鐘,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
針對每個k操作,在單獨的一行輸出答案。
Sample Input
X 4 4L 1 1 3 3 2
L 2 2 4 4 1
k 2 2 3 3
Sample Output
12HINT
對於100%的數據,1 ≤ n ≤ 2048, 1 ≤ m ≤ 2048, 1 ≤ abs(delta) ≤ 500,操作不超過200000個,保證運算過程中及最終結果均不超過32位帶符號整數類型的表示範圍。
題解
二維樹狀數組區間修改區間查詢。。。
公式其實挺好推的,從一維擴展道二維就行。。。
反正就是維護下v[i][j]、v[i][j]*i、v[i][j]*j
代碼
//by 減維 #include<cstdio> #include<iostream> #include<cstring> #include<queue> #include<cstdlib> #include<ctime> #include<cmath> #include<map> #include<bitset> #include<algorithm> #define ll long long using namespace std; int n,m; int lowbit(int x){return x&(-x);} struct tree{ int sum[2050][2050]; void change(int x,int y,int v) { for(int i=x;i<=n;i+=lowbit(i)) for(int j=y;j<=m;j+=lowbit(j)) sum[i][j]+=v; } int ask(int x,int y) { int ans=0; for(int i=x;i;i-=lowbit(i)) for(int j=y;j;j-=lowbit(j)) ans+=sum[i][j]; return ans; } }t1,t2,t3,t4; int calc(int x,int y) { return t1.ask(x,y)*(x+1)*(y+1)+t4.ask(x,y)-t2.ask(x,y)*(y+1)-t3.ask(x,y)*(x+1); } int main() { char op[5]; scanf("%s%d%d",op,&n,&m); int a,b,c,d,val; while(~scanf("%s",op)){ if(op[0]==‘L‘){ scanf("%d%d%d%d%d",&a,&b,&c,&d,&val); t1.change(a,b,val); t1.change(c+1,d+1,val); t1.change(a,d+1,-val); t1.change(c+1,b,-val); t2.change(a,b,val*a); t2.change(c+1,d+1,val*(c+1)); t2.change(a,d+1,-val*a); t2.change(c+1,b,-val*(c+1)); t3.change(a,b,val*b); t3.change(c+1,d+1,val*(d+1)); t3.change(a,d+1,-val*(d+1)); t3.change(c+1,b,-val*b); t4.change(a,b,val*a*b);t4.change(c+1,d+1,val*(c+1)*(d+1));t4.change(a,d+1,-val*a*(d+1));t4.change(c+1,b,-val*(c+1)*b); }else{ scanf("%d%d%d%d",&a,&b,&c,&d); printf("%d\n",calc(c,d)-calc(c,b-1)-calc(a-1,d)+calc(a-1,b-1)); } } return 0; }
【樹狀數組】BZOJ3132 上帝造題的七分鐘