bzoj 1452: [JSOI2009]Count

1452: [JSOI2009]Count

Description

Input

Output

Sample Input



Sample Output

1
2

HINT

 

题解:
很明显的一道RMQ问题
二维的线段树会爆数组,我们用二维树状数组。。

f[x][y][p]表示(1,1)~(x,y)之间的颜色是p的点的个数。
我们用一维的方法进行更新以及询问

最后 询问的话,几个矩形减减加加就可以啦(画画图吧)。。

#include<stdio.h>
#include<iostream>
#include<algorithm>
using namespace std;
int ans,n,m,p,i,j,x,y,z,T,x2,y2;
int f[305][305][105],a[305][305];
void update(int x,int y,int p,int z)
{
    int i,j;
    for(i=x;i<=n;i+=i&-i)
     for(j=y;j<=m;j+=j&-j)
     f[i][j][p]+=z;
}
int solve(int x,int y,int p)
{
    int i,j,ans=0;
    for(i=x;i;i-=i&-i)
     for(j=y;j;j-=j&-j)
     ans+=f[i][j][p];
    return ans;
}
int main()
{
    scanf("%d%d",&n,&m);
    for(i=1;i<=n;i++)
    {
        for(j=1;j<=m;j++)
        {
            scanf("%d",&a[i][j]);
            update(i,j,a[i][j],1);
        }
    }
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&p);
        if(p==1)
        {
            scanf("%d%d%d",&x,&y,&z);
            update(x,y,a[x][y],-1);
            update(x,y,z,1);
            a[x][y]=z;
        } else
        {
            scanf("%d%d%d%d%d",&x,&x2,&y,&y2,&z);
            ans=solve(x2,y2,z)-solve(x2,y-1,z)-solve(x-1,y2,z)+solve(x-1,y-1,z);
            printf("%d\n",ans);
        }
    }
    return 0;
}

 

posted @ 2016-05-10 20:50  lwq12138  阅读(157)  评论(0编辑  收藏  举报