1. 程式人生 > >【樹狀數組】BZOJ3132 上帝造題的七分鐘

【樹狀數組】BZOJ3132 上帝造題的七分鐘

-s 文件 輸入 二叉 ios pan 鋼琴 數據結構 頂點

3132: 上帝造題的七分鐘

Time Limit: 20 Sec Memory Limit: 128 MB
Submit: 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 4
L 1 1 3 3 2
L 2 2 4 4 1
k 2 2 3 3

Sample Output

12

HINT

對於100%的數據,1 ≤ n ≤ 2048, 1 ≤ m ≤ 2048, 1 ≤ abs(delta) ≤ 500,操作不超過200000個,保證運算過程中及最終結果均不超過32位帶符號整數類型的表示範圍。

題解

二維樹狀數組區間修改區間查詢。。。

公式其實挺好推的,從一維擴展道二維就行。。。

反正就是維護下v[i][j]v[i][j]*iv[i][j]*j

v[i][j]*i*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 上帝造題的七分鐘