BZOJ 1452: [JSOI2009]Count

本文介绍了一种使用二维树状数组优化矩阵查询的方法,针对一个N*M的方格进行权值更改和子矩阵中特定权值计数的操作。通过预处理和更新树状数组,实现了快速查询特定值出现次数的功能,适用于处理大量查询和更新。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Description

一个N*M的方格,初始时每个格子有一个整数权值,接下来每次有2个操作:

改变一个格子的权值

求一个子矩阵中某个特定权值出现的个数

Input

每一行有两个数字N,M

接下来N行,每行M个数字。第i+1行第j个数字表示格子(i,j)的初值

接下来输入一个Q,后面Q行每行描述一个操作

操作1:

1 x y c,表示将格子(x,y)的值变为c

操作2:

2 x1 x2 y1 y2 c,表示询问所有满足格子中数字为c的格子数字

(n,m<=300,Q<=5000)

(1<=x<=N,1<=y<=M,1<=c<=100)

(x1<=x<=x2,y1<=y<=y2)

Output

对于每个操作2,按输入中出现的顺序,依次输出一行一个整数表示所求得的个数

Sample Input

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

Sample Output

1
2

 

开c个二维树状数组,很水

 

#include<cstdio>
#define ll long long
using namespace std;
 
inline int read()
{
    int ret=0;
    char ch=getchar(); bool f=0;
    while(ch<'0'||ch>'9') 
    {
        if(ch=='-') f=1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9')
        ret=(ret<<1)+(ret<<3)+ch-'0',ch=getchar();
    return f?-ret:ret;
}
 
int n,m;
const int N=305,C=105;
int a[N][N],c[N][N][C];
 
inline void add(int x,int y,int co,int val)
{
    for(int i=x;i<=n;i+=i&-i)
        for(int j=y;j<=m;j+=j&-j)
            c[i][j][co]+=val;
}
 
inline int sum(int x,int y,int co)
{
    int ret=0;
    for(int i=x;i;i-=i&-i)
        for(int j=y;j;j-=j&-j)
            ret+=c[i][j][co];
    return ret;
}
int main()
{
    n=read(); m=read();
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            a[i][j]=read(),
            add(i,j,a[i][j],1);
             
    int q=read();
    while(q--)
    {
        int t=read();
        if(t==1) 
        {
            int x=read(),y=read();
            add(x,y,a[x][y],-1);
            add(x,y,a[x][y]=read(),1);
        } else
        {
            int x1=read(),x2=read(),y1=read(),y2=read(),co=read();
            printf("%d\n",sum(x2,y2,co)-sum(x1-1,y2,co)-sum(x2,y1-1,co)+sum(x1-1,y1-1,co));
        }
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值