【BZOJ-1452】Count 树状数组 套 树状数组

1452: [JSOI2009]Count

Time Limit: 10 Sec  Memory Limit: 64 MB
Submit: 1769  Solved: 1059
[Submit][Status][Discuss]

Description

Input

Output

Sample Input

Sample Output

1
2

HINT

Source

Solution

忽略标题的说法...撞壁用的....

简单题,裸树状数组套树状数组

颜色数目$c<=100$很小,考虑对于每种颜色单独进行处理

那么对于每个颜色单独开一个二维树状数组维护

另开一个二维数组记录下当前各个位置的颜色

1操作,将原有颜色树状数组中的$(x,y)$点置成0,在新颜色树状数组中置成1,并更新颜色的状态

2操作,区间查询,应用前缀和,进行一下加减即可得到当前子矩阵和

Code

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int read()
{
    int x=0,f=1; char ch=getchar();
    while (ch<‘0‘ || ch>‘9‘) {if (ch==‘-‘) f=-1; ch=getchar();}
    while (ch>=‘0‘ && ch<=‘9‘) {x=x*10+ch-‘0‘; ch=getchar();}
    return x*f;
}
int n,m,q;int zt[310][310];
struct Treenode
{
    int tree[310][310];
    Treenode(){memset(tree,0,sizeof(tree));}
    int lowbit(int x){return x&-x;}
    void change(int x,int y,int del)
        {
            for (int i=x; i<=n; i+=lowbit(i))
                for (int j=y; j<=m; j+=lowbit(j))
                    tree[i][j]+=del;
        }
    int query(int x,int y)
        {
            int ans=0;
            for (int i=x; i; i-=lowbit(i))
                for (int j=y; j; j-=lowbit(j))
                    ans+=tree[i][j];
            return ans;
        }
    int ask(int x1,int y1,int x2,int y2)
        {
            return query(x2,y2)-query(x2,y1-1)-query(x1-1,y2)+query(x1-1,y1-1);
        }
}color[110];

int main()
{
    n=read(); m=read();
    for (int i=1; i<=n; i++)
        for (int col,j=1; j<=m; j++)
            col=read(),color[col].change(i,j,1),zt[i][j]=col;
    q=read();
    for (int i=1; i<=q; i++)
        {
            int opt=read(),x1,y1,x2,y2,col;
            if (opt==1)
                {
                    x1=read(),y1=read(),col=read();
                    color[zt[x1][y1]].change(x1,y1,-1);
                    zt[x1][y1]=col;
                    color[col].change(x1,y1,1);
                    continue;
                }
            x1=read(),x2=read(),y1=read(),y2=read(),col=read();
            printf("%d\n",color[col].ask(x1,y1,x2,y2));
         }
    return 0;
}

5分钟不到,看、想、写、1A系列....

时间: 2024-09-30 14:55:50

【BZOJ-1452】Count 树状数组 套 树状数组的相关文章

【BZOJ】1047: [HAOI2007]理想的正方形(单调队列/~二维rmq+树状数组套树状数组)

http://www.lydsy.com/JudgeOnline/problem.php?id=1047 树状数组套树状数组真心没用QAQ....首先它不能修改..而不修改的可以用单调队列做掉,而且更快,只有O(n^2).而这货是n^2log^2n的建树...虽然查询是log^2n...但是建树那里就tle了.. 那么说题解... 先orz下,好神.. 我怎么没想到单调队列orz 首先我们维护 行 的单调队列,更新每个点在 列 距离内的最小and最大的值 然后我们维护 列 的单调队列,更新每个点

BZOJ 2588 Count on a tree 主席树+倍增LCA

题目大意:给定一棵树,每个节点有权值,询问两个节点路径上的权值第k小 这题很卡时间... 树链剖分+二分+树套树的O(nlog^4n)做法可以去死了 没有修改操作,树链剖分+二分+划分树O(nlog^3n),还是死了 我怒了,裸学了一发可持久化线段树(不看任何代码OTZ,我是怎么做到的0.0),二分+主席树,O(nlog^2n),居然还是死了! 最后发现我SB了,完全没有必要二分,直接把4个参全传下去就行了,O(nlogn) 首先我们对于每个节点维护这个节点到根的权值线段树 然后对于每个询问(x

树链剖分套树状数组(区间修改)板子

P3384 [模板]树链剖分 题目描述 如题,已知一棵包含N个结点的树(连通且无环),每个节点上包含一个数值,需要支持以下操作: 操作1: 格式: 1 x y z 表示将树从x到y结点最短路径上所有节点的值都加上z 操作2: 格式: 2 x y 表示求树从x到y结点最短路径上所有节点的值之和 操作3: 格式: 3 x z 表示将以x为根节点的子树内所有节点值都加上z 操作4: 格式: 4 x 表示求以x为根节点的子树内所有节点值之和 输入输出格式 输入格式:   第一行包含4个正整数N.M.R.

BZOJ 1452 Count

长知识啦..二维BIT. #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; int n,m,q,t[105][305][305],map[305][305]; int a,b,c,d,e,f; int lowbit(int x) { return x&(-x); } void update(int x,int y

BZOJ 1452: [JSOI2009]Count (二维树状数组)

Description Input Output Sample Input Sample Output 1 2 HINT 二维树状数组的简单应用,c数组的第一维坐标相当于哈希.如果是修改操作,修改前 将当前的值的个数以及祖先都减1, 修改后将个数加1. #include <iostream> #include <cstring> #include <cstdio> #include <cmath> #include <set> #include

【BZOJ】1146: [CTSC2008]网络管理Network(树链剖分+线段树套平衡树+二分 / dfs序+树状数组+主席树)

第一种做法(时间太感人): 这题我真的逗了,调了一下午,疯狂造数据,始终找不到错. 后来发现自己sb了,更新那里没有打id,直接套上u了.我.... 调了一下午啊!一下午的时光啊!本来说好中午A掉去学习第二种做法,噗 好吧,现在第一种做法是hld+seg+bst+二分,常数巨大,log^4级别,目前只会这种. 树剖后仍然用线段树维护dfs序区间,然后在每个区间建一颗平衡树,我用treap,(这题找最大啊,,,囧,并且要注意,这里的rank是比他大的数量,so,我们在二分时判断要判断一个范围,即要

[BZOJ 3196] 213平衡树 【线段树套set + 树状数组套线段树】

题目链接:BZOJ - 3196 题目分析 区间Kth和区间Rank用树状数组套线段树实现,区间前驱后继用线段树套set实现. 为了节省空间,需要离线,先离散化,这样需要的数组大小可以小一些,可以卡过128MB = = 嗯就是这样,代码长度= =我写了260行......Debug了n小时= = 代码 #include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #in

[BZOJ 1901] Dynamic Rankings 【树状数组套线段树 || 线段树套线段树】

题目链接:BZOJ - 1901 题目分析 树状数组套线段树或线段树套线段树都可以解决这道题. 第一层是区间,第二层是权值. 空间复杂度和时间复杂度均为 O(n log n). 代码 树状数组套线段树 #include <iostream> #include <cstdlib> #include <cstdio> #include <cmath> #include <algorithm> #include <cstring> usin

BZOJ 3196 Tyvj 1730 二逼平衡树 ——树状数组套主席树

[题目分析] 听说是树套树.(雾) 怒写树状数组套主席树,然后就Rank1了.23333 单点修改,区间查询+k大数查询=树状数组套主席树. [代码] #include <cstdio> #include <cstring> #include <cstdlib> #include <cmath> #include <set> #include <map> #include <string> #include <alg