计数问题
时间限制: 1 Sec 内存限制: 128 MB提交: 185 解决: 51
[ 提交][ 状态][ 讨论版][命题人: admin]
题目描述
一个n*m的方格,初始时每个格子有一个整数权值。接下来每次有2种操作:
改变一个格子的权值;
求一个子矩阵中某种特定权值出现的个数。
改变一个格子的权值;
求一个子矩阵中某种特定权值出现的个数。
输入
第一行有两个数n,m。
接下来n行,每行m个数,第i+1行第j个数表示格子(i,j)的初始权值。
接下来输入一个整数q。
接下来q行,每行描述一个操作。
操作1:“1 x y c”(不含双引号)。表示将格子(x,y)的权值改成c(1<=x<=n,1<=y<=m,1<=c<=100)。
操作2:“2 x1 x2 y1 y2 c”(不含双引号,x1<=x2,y1<=y2)。表示询问所有满足格子权值为c,且x1<=x<=x2,y1<=y<=y2的格子(x,y)的个数。
接下来n行,每行m个数,第i+1行第j个数表示格子(i,j)的初始权值。
接下来输入一个整数q。
接下来q行,每行描述一个操作。
操作1:“1 x y c”(不含双引号)。表示将格子(x,y)的权值改成c(1<=x<=n,1<=y<=m,1<=c<=100)。
操作2:“2 x1 x2 y1 y2 c”(不含双引号,x1<=x2,y1<=y2)。表示询问所有满足格子权值为c,且x1<=x<=x2,y1<=y<=y2的格子(x,y)的个数。
输出
对于每个操作2,按照在输入中出现的顺序,依次输出一行一个整数表示所求得的个数。
样例输入
3 3
1 2 3
3 2 1
2 1 3
3
2 1 2 1 2 1
1 2 3 2
2 2 3 2 3 2
样例输出
1
2
提示
对于30%的数据n,m<=30,q<=10000
对于100%的数据 n,m<=300,q<=100000,1<=c<=100
RMQ 查询问题;
m次查询 很且数量很大, 所以想到往树状数组上靠拢, 然后 这个地方又是 统计 x,y 的 那就时二维树状数组
但题意 又要 求 某个数的个数, 所以 tree【】【】【】 开到三维, C不到100 很ok
更新时, 先把 对应的位置上的数 全部-1 然后再把要变成的值+1 保证 全部变成, 并且更新节点
[code]
#include <iostream>
#include <bits/stdc++.h>
#include <string.h>
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
const int MOD=1e9+7;
const int MAXN=1e5+15;
const int INF=0x3f3f3f3f;
typedef long long ll;
inline ll qpow(ll x,ll n){ll res=1;for(;n;n>>=1){if(n&1)res=(res*x);x=(x*x);}return res;}
const int N=305;
int a[310][310];
int tree[305][305][105];
int n,m;
int lowbit(int x)
{
return x&(-x);
}
void update(int x,int y,int c,int k )
{
int i, j;
for(i=x;i<=m;i+=lowbit(i))
{
for(j=y; j<=n; j+=lowbit(j))
{
tree[i][j][c] += k;
}
}
}
int Sum( int x, int y ,int c)
{
int res=0,i,j;
for(i=x;i>0;i-=lowbit(i))
{
for(j=y; j>0; j-=lowbit(j))
{
res += tree[i][j][c];
}
}
return res;
}
int main()
{
scanf("%d %d",&n,&m);
int sum=0;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
scanf("%d",&a[i][j]);
update(i,j,a[i][j],1);
}
}
int q;
scanf("%d",&q);
while(q--)
{
int f;
scanf("%d",&f);
if(f==1)
{
int x,y,z;
scanf("%d %d %d",&x,&y,&z);
update(x,y,a[x][y],-1);
update(x,y,z,1);
a[x][y]=z;
}
else
{
int x1,x2,y1,y2,z;
scanf("%d %d %d %d %d",&x1,&x2,&y1,&y2,&z);
int sum= Sum(x2,y2,z)-Sum(x2,y1-1,z)-Sum(x1-1,y2,z)+Sum(x1-1,y1-1,z);
printf("%d\n",sum);
}
}
return 0;
}
123