bzoj 1452 二维树状数组

  每一种颜色存一颗二维树状数组,然后直接做就行了。

/**************************************************************
    Problem: 1452
    User: BLADEVIL
    Language: C++
    Result: Accepted
    Time:4844 ms
    Memory:36904 kb
****************************************************************/
 
//By BLADEVIL
#include <cstdio>
#include <cstring>
#define maxn 301
#define maxc 101
 
using namespace std;
 
int map[maxn][maxn];
int n,m,task;
struct rec{
    int c[maxn][maxn];
    rec(){memset(c,0,sizeof c);}
    void change(int i,int j,int d){
        for (int x=i;x<=n;x+=x&-x)
            for (int y=j;y<=m;y+=y&-y)
                c[x][y]+=d;
    }
    int sum(int i,int j){
        int ans=0;
        for (int x=i;x;x-=x&-x)
            for (int y=j;y;y-=y&-y)
                ans+=c[x][y];
        return ans;
    }
    int sum(int x,int y,int xx,int yy){
        return sum(xx,yy)-sum(x-1,yy)-sum(xx,y-1)+sum(x-1,y-1);
    }
} w[maxc];
 
void change(int x,int y,int z){
    int k=map[x][y];
    w[k].change(x,y,-1);
    w[z].change(x,y,1);
    map[x][y]=z;
}
 
int main(){
    int x,y,xx,yy,z;
    scanf("%d%d",&n,&m);
    for (int i=1;i<=n;i++)
        for (int j=1;j<=m;j++) scanf("%d",&map[i][j]),w[map[i][j]].change(i,j,1);
    scanf("%d",&task);
    while (task--){
        int k; scanf("%d",&k);
        if (k==1){
            scanf("%d%d%d",&x,&y,&z);
            change(x,y,z);
        } else {
            scanf("%d%d%d%d%d",&x,&xx,&y,&yy,&z);
            printf("%d\n",w[z].sum(x,y,xx,yy));
        }
    }
    return 0;   
}

 

posted on 2014-02-26 17:05  BLADEVIL  阅读(331)  评论(0编辑  收藏  举报