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;   

}

 

你可能感兴趣的:(树状数组)