BZOJ3132: 上帝造题的七分钟

题解:多个树树状数组的妙用

#include <bits/stdc++.h>
//#define ll long long
const int MAXN=2050;
using namespace std;
int a[MAXN][MAXN],b[MAXN][MAXN],c[MAXN][MAXN],d[MAXN][MAXN];
int n,m;
int get_id(int x){return x&(-x);}
void add1(int x,int y,int vul){
    for(int i=x;i<=n;i+=get_id(i)){
	for(int j=y;j<=m;j+=get_id(j))a[i][j]+=vul;
    }
}
void add2(int x,int y,int vul){
    for(int j=y;j<=m;j+=get_id(j)){
	for(int i=x;i>0;i-=get_id(i))b[i][j]+=vul;
    }
}
void add3(int x,int y,int vul){
    for(int i=x;i<=n;i+=get_id(i)){
	for(int j=y;j>0;j-=get_id(j))c[i][j]+=vul;
    }
}
void add4(int x,int y,int vul){
    for(int i=x;i>0;i-=get_id(i)){
	for(int j=y;j>0;j-=get_id(j))d[i][j]+=vul;
    }
}
int querty1(int x,int y){
    int ans=0;
    for(int i=x;i>0;i-=get_id(i)){
	for(int j=y;j>0;j-=get_id(j))ans+=a[i][j];
    }
    return ans;
}
int querty2(int x,int y){
    int ans=0;
    for(int i=x;i<=n;i+=get_id(i)){
	for(int j=y;j>0;j-=get_id(j))ans+=b[i][j]*(x);
    }
    return ans;
}
int querty3(int x,int y){
    int ans=0;
    for(int j=y;j<=m;j+=get_id(j)){
	for(int i=x;i>0;i-=get_id(i))ans+=c[i][j]*(y);
    }
    return ans;
}
int querty4(int x,int y){
    int ans=0;
    for(int i=x;i<=n;i+=get_id(i)){
	for(int j=y;j<=m;j+=get_id(j))ans+=d[i][j];
    }
    return ans;
}
char str[11];
int h[5];
void update(int x,int y,int vul){
    add1(x+1,y+1,x*y*vul);
    add2(x,y+1,y*vul);
    add3(x+1,y,x*vul);
    add4(x,y,vul);
}
int Sum(int x,int y){
    int res=0;
    res+=querty1(x,y);
   // cout<<"res== "<<" "<<res<<endl;
    res+=querty2(x,y);
   // cout<<"res= "<<res<<endl;
    res+=querty3(x,y);
   // cout<<"res= "<<res<<endl;
    res+=querty4(x,y)*x*y;
    return res;
}
int main(){
    scanf(" %s%d%d",str,&n,&m);n++;m++;
    int vul;
    while(scanf(" %s",str)!=EOF){
	for(int i=1;i<=4;i++)scanf("%d",&h[i]),h[i]++;
	if(str[0]=='L'){
	    scanf("%d",&vul);
	    update(h[3],h[4],vul);
	   // cout<<Sum(2,2)<<"::::"<<" "<<vul<<endl;
	    update(h[1]-1,h[2]-1,vul);
	   // cout<<"左下角:::  "<<" "<<Sum(2,2)<<endl;
	    update(h[1]-1,h[4],-1*vul);
	  //  cout<<"左上角:: "<<Sum(2,2)<<endl;
	    update(h[3],h[2]-1,-1*vul);
	   // cout<<Sum(2,2)<<endl;
	}
	else if(str[0]=='k'){
	    printf("%d\n",Sum(h[3],h[4])-Sum(h[1]-1,h[4])-Sum(h[3],h[2]-1)+Sum(h[1]-1,h[2]-1));
	}
//	cout<<Sum(4,2)<<endl;
//	cout<<querty2(4,2)<<endl;
    }
    return 0;
}

 

posted @ 2018-07-24 15:35  wang9897  阅读(98)  评论(0编辑  收藏  举报