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

sukimo

2020-06-26 17:18:16

Solution

可以说是二维$BIT$单点修改区间查询的板子题。原理和一维$BIT$类似。考虑到数据规模不大,可以对于每一个权值开一个$BIT$,然后修改时对于原权值的$BIT$对应位置$--$,新权值的$BIT$对应位置$++$。 代码: ``` #include<bits/stdc++.h> #define MXq 200005 using namespace std; int n,m,mat[305][305],ans[MXq],tree[105][305][305]; int lowbit(int x){return x&-x;} void add(int type,int x,int y,int v){ while(x<=n){ int _y=y;while(_y<=m){tree[type][x][_y]+=v;_y+=lowbit(_y);}x+=lowbit(x); } } int pref(int type,int x,int y){ int tot=0; while(x>=1){ int _y=y;while(_y>=1){tot+=tree[type][x][_y];_y-=lowbit(_y);}x-=lowbit(x); } return tot; } int query(int type,int x1,int y1,int x2,int y2){ return pref(type,x2,y2)+pref(type,x1-1,y1-1)-pref(type,x1-1,y2)-pref(type,x2,y1-1); } int main(){ int q,_top=0;cin>>n>>m; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) {cin>>mat[i][j];add(mat[i][j],i,j,1);} cin>>q; for(int i=1;i<=q;i++){ int _q;cin>>_q; if(_q==1){ int x,y,c;cin>>x>>y>>c;add(mat[x][y],x,y,-1);add(c,x,y,1);mat[x][y]=c; } else{ int x1,y1,x2,y2,c;cin>>x1>>x2>>y1>>y2>>c; ans[++_top]=query(c,x1,y1,x2,y2); } } for(int i=1;i<=_top;i++)cout<<ans[i]<<endl; return 0; } ```