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;	
    }
    
  • 相关阅读:
    java基础 Collections.sort的两种用法
    Mysql常用命令详解
    2、Java并发编程:如何创建线程
    JAR、WAR、EAR的使用和区别
    区分Oracle的数据库,实例,服务名,SID
    Mysql 启动运行
    3、Java并发编程:Thread类的使用
    1、Java多线程基础:进程和线程之由来
    文件上传利器SWFUpload使用指南
    网络矩阵
  • 原文地址:https://www.cnblogs.com/wzj-xhjbk/p/10447101.html
Copyright © 2011-2022 走看看