zoukankan      html  css  js  c++  java
  • BZOJ1452 [JSOI2009]Count 树状数组

    欢迎访问~原文出处——博客园-zhouzhendong

    去博客园看该题解


     题目传送门 - BZOJ1452


    题意概括

      一个n*m的矩阵,现在有2种操作:

    1. 修改某一个位置的值
    2. 求一个子矩阵某值的出现次数

      n , m ≤ 300 ,  1 ≤ 元素的值 ≤ 100 , 操作次数 ≤ 200000


    题解

      100棵二维树状数组。维护每个值的二维前缀出现次数。

      好像该说的都说了……


    代码

    #include <cstring>
    #include <algorithm>
    #include <cstdio>
    #include <cstdlib>
    #include <cstdio>
    using namespace std;
    const int N=300+5,C=100+5;
    int n,m,q,a[N][N],t[C][N][N];
    int lowbit(int x){
    	return x&-x;
    }
    void add(int c,int x,int y,int d){
    	for (int i=x;i<=n;i+=lowbit(i))
    		for (int j=y;j<=m;j+=lowbit(j))
    			t[c][i][j]+=d;
    }
    int sum(int c,int x,int y){
    	int ans=0;
    	for (int i=x;i>0;i-=lowbit(i))
    		for (int j=y;j>0;j-=lowbit(j))
    			ans+=t[c][i][j];
    	return ans;
    }
    int main(){
    	scanf("%d%d",&n,&m);
    	memset(t,0,sizeof t);
    	for (int i=1;i<=n;i++)
    		for (int j=1;j<=m;j++){
    			scanf("%d",&a[i][j]);
    			add(a[i][j],i,j,1);
    		}
    	scanf("%d",&q);
    	while (q--){
    		int type,c;
    		scanf("%d",&type);
    		if (type==1){
    			int x,y;
    			scanf("%d%d%d",&x,&y,&c);
    			add(a[x][y],x,y,-1);
    			a[x][y]=c;
    			add(a[x][y],x,y,1);
    		}
    		else {
    			int x1,y1,x2,y2;
    			scanf("%d%d%d%d%d",&x1,&x2,&y1,&y2,&c);
    			printf("%d
    ",sum(c,x2,y2)-sum(c,x1-1,y2)-sum(c,x2,y1-1)+sum(c,x1-1,y1-1));
    		}
    	}
    	return 0;
    }
    /*
    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
    */
    

      

  • 相关阅读:
    JS 日期加多少天,减多少天
    SQL 触发器
    SGU100
    连续子数组的最大和
    字符串的排列
    二叉搜索树与双向链表
    数组中出现次数超过一半的数字
    复杂链表的复制
    二叉树中和为某一值的路径
    二叉搜索树的后序遍历序列
  • 原文地址:https://www.cnblogs.com/zhouzhendong/p/BZOJ1452.html
Copyright © 2011-2022 走看看