P4224矩阵计数
时间限制 : - MS 空间限制 : 65536 KB
评测说明 : 1s
问题描述
给出一个n*m的方格矩阵,每个格子里都有一个整数。你有两种操作:
"1 x y k" 将坐标为x,y的格子的数字改为k;
"2 x1 y1 x2 y2 k"询问满足值为k且坐标(x,y) x1<=x<=x2 ,y1<=y<=y2的格子的数量
输入格式
第一行,两个整数n和m
接下来一个n*m的整数矩阵,表示矩阵的初始情况。
接下来一行,一个整数Q,表示有Q个操作:
操作1:"1 x y k" 将坐标为x,y的格子的数字改为k;
操作2:"2 x1 y1 x2 y2 k"询问满足值为k且坐标x1<=x<=x2 ,y1<=y<=y2的格子的数量
输出格式
对于每个2号操作,输出一行,一个整数,表示查询结果
样例输入 1
3 3
1 2 3
3 2 1
2 1 3
3
2 1 1 2 2 1
1 2 3 2
2 2 2 3 3 2
样例输出 1
1
2
样例输入 2
5 5
4 3 4 5 3
2 5 4 1 3
5 2 3 4 4
2 5 3 3 3
5 1 1 1 3
6
2 1 1 5 3 1
1 2 2 2
1 2 3 4
2 2 1 5 3 2
1 4 4 2
2 1 1 3 5 2
样例输出 2
2
4
3
提示
对于30%的数据:n,m<=30 Q<=5000
对于100%的数据:
n,m<=300 Q<=200000 k<=100
1<=x,x1,x2<=n 1<=y,y1,y2<=m x1<=x2 y1<=y2
来源 改编自jsoi2009 count
由于这道题目太过于直接,没有任何剧情,所以我也没啥好吐槽的…
题解
思路
这道题目的解法其实很暴力
我们知道在某一个二维矩阵里头增加标记1时的操作和计数,就是使用二维树状数组
那么如何在一个二维矩阵当中增加某一个数字的标记呢??
我们就多开一维嘛
我们给每一个数字开一个二维矩阵,当原矩阵当中的某个位置是某个数字时,我们就在该数字的矩阵的相应位置标个1
例如
1 2 3
4 5 6
1 2 3
那么对应的数字1的矩阵为
1 0 0
0 0 0
1 0 0
对应数字5的矩阵为
0 0 0
0 1 0
0 0 0
这个样子,我们就能够轻易地进行改动,操作与二维树状数组的修改和统计操作基本相同
注意
我们在修改某个位置的数字时,要先将该位置的原数字标记取消掉,在添加新的标记
例如
原矩阵
1 2 3
3 2 1
我们将3 1上的数字3修改为1
那么
3的矩阵将由
0 0 1
1 0 0
变为
0 0 0
1 0 0
1的矩阵将由
1 0 0
0 0 1
变为
1 0 1
0 0 1
不懂二维树状数组操作的请自行百度…确实讲起很麻烦
附上代码
#include <iostream>
#include <cstdio>
using namespace std;
int n,m;
int maps[345][345],C[123][312][312];
inline int input()
{
char c=getchar();int o;
while(c>57||c<48)c=getchar();
for(o=0;c>47&&c<58;c=getchar())o=(o<<1)+(o<<3)+c-48;
return o;
}
int lowbit(int x){return x&-x;}
void add(int x,int y,int num,int d)
{
for(int a=x;a<=n;a+=lowbit(a))
for(int b=y;b<=m;b+=lowbit(b))
C[num][a][b]+=d;
}
int sum(int x,int y,int num)
{
int ans=0;
for(int a=x;a;a-=lowbit(a))
for(int b=y;b;b-=lowbit(b))
ans+=C[num][a][b];
return ans;
}
int main()
{
int xo,yo,xt,yt,num,t,q;
n=input();m=input();
for(int x=1;x<=n;x++)
for(int y=1;y<=m;y++)
{
maps[x][y]=input();
add(x,y,maps[x][y],1);
}
t=input();
for(int i=1;i<=t;i++)
{
q=input();
if(q==2)
{
xo=input()-1;yo=input()-1;xt=input();yt=input();num=input();
printf("%d\n",sum(xt,yt,num)+sum(xo,yo,num)-sum(xo,yt,num)-sum(xt,yo,num));
}
else
{
xo=input();yo=input();num=input();
add(xo,yo,maps[xo][yo],-1);
maps[xo][yo]=num;
add(xo,yo,num,1);
}
}
return 0;
}