bzoj 1452 //1452:[JSOI2009] Count //[JSOI2009]计数问题 二维树状数组

bzoj 1452 //1452:[JSOI2009] Count  //[JSOI2009]计数问题   //在线测评地址https://www.lydsy.com/JudgeOnline/problem.php?id=1452

更多题解,详见https://blog.csdn.net/mrcrack/article/details/90228694BZOJ刷题记录

bzoj 1452

39340 kb 6128 ms C++/Edit 1308 B

洛谷2.75s / 38.41MB / 1.09KB C++

//1452:[JSOI2009] Count
//[JSOI2009]计数问题
//在线测评地址https://www.luogu.org/problem/P4054
//枚举算法也就30分,很好奇 二维树状数组 算法
//此文http://hzwer.com/3251.html代码写得不错,边看边画图,应该能很快看懂。
/*
发现第一次写二维树状数组
妈蛋就是多了一层for。。。
对于每种颜色开一个二维树状数组水过。。。
*/
//ans=ask(x2,y2,c)-ask(x1-1,y2,c)-ask(x2,y1-1,c)+ask(x1-1,y1-1,c);的理解详见下图

bzoj 1452 //1452:[JSOI2009] Count //[JSOI2009]计数问题 二维树状数组_第1张图片

//编写过程中,树状数组update,ask写了两个奇杷的代码,如下,错误的
/*
void update(int x,int y,int c,int v){
    while(x<=n){
        while(y<=m){
            C[x][y][c]+=v;
            y+=lowbit(y);
        }
        x+=lowbit(x);
    }
}
int ask(int x,int y,int c){
    int ans=0;
    while(x>0){
        while(y>0){
            ans+=C[x][y][c];
            y-=lowbit(y);
        }
        x-=lowbit(x);
    }
    return ans;//漏了此句,查了10分钟
}
*/
//上述代码错误的原因在于y只在x的第一次循环起作用,之后,值就固定不变了。这个查了30分钟,才发现。
//样例通过,提交AC.2019-10-16 20:47
#include
#include
#define maxn 305
int n,m,map[maxn][maxn],C[maxn][maxn][105];//1<=c<=100
int lowbit(int x){
    return x&-x;
}
void update(int x,int y,int c,int v){
    int i,j;
    for(i=x;i<=n;i+=lowbit(i))
        for(j=y;j<=m;j+=lowbit(j))
            C[i][j][c]+=v;
}
int ask(int x,int y,int c){
    int ans=0,i,j;
    for(i=x;i>0;i-=lowbit(i))
        for(j=y;j>0;j-=lowbit(j))
            ans+=C[i][j][c];
    return ans;//漏了此句,查了10分钟
}
int main(){
    int i,j,q,cmd,x1,y1,x2,y2,c,ans;
    memset(C,0,sizeof(C));
    scanf("%d%d",&n,&m);
    for(i=1;i<=n;i++)
        for(j=1;j<=m;j++)
            scanf("%d",&map[i][j]),update(i,j,map[i][j],1);
    scanf("%d",&q);
    while(q--){
        scanf("%d",&cmd);
        if(cmd==1){
            scanf("%d%d%d",&x1,&y1,&c);
            update(x1,y1,map[x1][y1],-1);
            map[x1][y1]=c;
            update(x1,y1,map[x1][y1],1);
        }
        else if(cmd==2){
            scanf("%d%d%d%d%d",&x1,&x2,&y1,&y2,&c);
            ans=ask(x2,y2,c)-ask(x1-1,y2,c)-ask(x2,y1-1,c)+ask(x1-1,y1-1,c);
            printf("%d\n",ans);
        }
    }
    return 0;
}

 

 

你可能感兴趣的:(跟着大佬学算法)