zoukankan      html  css  js  c++  java
  • 【洛谷P4054】计数问题

    题目大意:维护 N*M 个点,每个点有三个权值,支持单点修改,查询矩形区间内权值等于某个值的点的个数。

    题解:矩阵可以看成两个维度,权值为第三个维度,为一个三维偏序维护问题。发现第三维仅仅为单点修改和单点询问,直接用数组实现最简单,且空间足够。因此,直接建立 100 个二维树状数组,转变成为单点修改,矩形查询的问题。

    代码如下

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn=301;
    
    int n,m,q;
    int t[101][maxn][maxn],d[maxn][maxn];
    inline int lowbit(int x){return x&-x;}
    inline void modify(int o,int x,int y,int val){
    	for(int i=x;i<=n;i+=lowbit(i))
    		for(int j=y;j<=m;j+=lowbit(j))
    			t[o][i][j]+=val;
    }
    inline int query(int o,int x,int y){
    	int res=0;
    	for(int i=x;i;i-=lowbit(i))
    		for(int j=y;j;j-=lowbit(j))
    			res+=t[o][i][j];
    	return res;
    }
    
    void read_and_parse(){
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=n;i++)
    		for(int j=1;j<=m;j++){
    			scanf("%d",&d[i][j]);
    			modify(d[i][j],i,j,1);
    		}
    }
    
    void solve(){
    	scanf("%d",&q);
    	while(q--){
    		int opt;
    		scanf("%d",&opt);
    		if(opt==1){
    			int x,y,c;scanf("%d%d%d",&x,&y,&c);
    			modify(d[x][y],x,y,-1),modify(d[x][y]=c,x,y,1);
    		}else{
    			int x1,y1,x2,y2,c;scanf("%d%d%d%d%d",&x1,&x2,&y1,&y2,&c);
    			printf("%d
    ",query(c,x2,y2)-query(c,x1-1,y2)-query(c,x2,y1-1)+query(c,x1-1,y1-1));
    		}
    	}
    }
    
    int main(){
    	read_and_parse();
    	solve();
    	return 0;	
    }
    
  • 相关阅读:
    前端之script标签注意事项
    前端之常用网址的整理
    前端之清除浮动
    三元表达式
    迭代器 生成器
    文件处理流程
    python中常见的内置函数
    匿名函数lambda
    模拟问路场景理解递归
    create auto increment row with select in postgreSQL
  • 原文地址:https://www.cnblogs.com/wzj-xhjbk/p/10447101.html
Copyright © 2011-2022 走看看