【题解】Luogu P4054 [JSOI2009]计数问题

原题传送门

我自闭了qaq

这道题非常简单,因为1<=c<=100,所以直接对每个c开二维树状数组,操作就跟模板一样

写码5分钟,调码半小时,这道题的输入顺序是x1,x2,y1,y2,我真的自闭了

#include <bits/stdc++.h>
#define getchar nc
#define N 305
#define C 105
using namespace std;
inline char nc(){
    static char buf[100000],*p1=buf,*p2=buf; 
    return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++; 
}
inline int read()
{
    register int x=0,f=1;register char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
    return x*f;
}
inline void write(register int x)
{
    if(!x)putchar('0');if(x<0)x=-x,putchar('-');
    static int sta[20];register int tot=0;
    while(x)sta[tot++]=x%10,x/=10;
    while(tot)putchar(sta[--tot]+48);
}
int n,m,q;
int tr[N][N][C];
int c[N][N];
inline int lowbit(register int x)
{
    return x&(-x);
}
inline void update(register int x,register int y,register int co,register int cn)
{
    for(register int i=x;i<=n;i+=lowbit(i))
        for(register int j=y;j<=m;j+=lowbit(j))
        {
            --tr[i][j][co];
            ++tr[i][j][cn];
        }
}
inline int query(register int x,register int y,register int cq)
{
    int res=0;
    for(register int i=x;i;i-=lowbit(i))
        for(register int j=y;j;j-=lowbit(j))
            res+=tr[i][j][cq];
    return res;
}
int main()
{
    n=read(),m=read();
    for(register int i=1;i<=n;++i)
        for(register int j=1;j<=m;++j)
        {
            c[i][j]=read();
            update(i,j,0,c[i][j]);
        }
    q=read();
    while(q--)
    {
        int opt=read();
        if(opt==1)
        {
            int x=read(),y=read(),cn=read();
            update(x,y,c[x][y],cn);
            c[x][y]=cn;
        }
        else
        {
            int a=read(),x=read(),b=read(),y=read(),cq=read();
            write(query(x,y,cq)-query(x,b-1,cq)-query(a-1,y,cq)+query(a-1,b-1,cq)),puts("");
        }
    }
    return 0;
 } 

猜你喜欢

转载自www.cnblogs.com/yzhang-rp-inf/p/10235924.html