bzoj 1452: [JSOI2009]Count
1452: [JSOI2009]Count
Description
Input
Output
Sample Input
Sample Output
1
2
2
HINT
题解:
很明显的一道RMQ问题
二维的线段树会爆数组,我们用二维树状数组。。
f[x][y][p]表示(1,1)~(x,y)之间的颜色是p的点的个数。
我们用一维的方法进行更新以及询问
最后 询问的话,几个矩形减减加加就可以啦(画画图吧)。。
#include<stdio.h> #include<iostream> #include<algorithm> using namespace std; int ans,n,m,p,i,j,x,y,z,T,x2,y2; int f[305][305][105],a[305][305]; void update(int x,int y,int p,int z) { int i,j; for(i=x;i<=n;i+=i&-i) for(j=y;j<=m;j+=j&-j) f[i][j][p]+=z; } int solve(int x,int y,int p) { int i,j,ans=0; for(i=x;i;i-=i&-i) for(j=y;j;j-=j&-j) ans+=f[i][j][p]; return ans; } int main() { scanf("%d%d",&n,&m); for(i=1;i<=n;i++) { for(j=1;j<=m;j++) { scanf("%d",&a[i][j]); update(i,j,a[i][j],1); } } scanf("%d",&T); while(T--) { scanf("%d",&p); if(p==1) { scanf("%d%d%d",&x,&y,&z); update(x,y,a[x][y],-1); update(x,y,z,1); a[x][y]=z; } else { scanf("%d%d%d%d%d",&x,&x2,&y,&y2,&z); ans=solve(x2,y2,z)-solve(x2,y-1,z)-solve(x-1,y2,z)+solve(x-1,y-1,z); printf("%d\n",ans); } } return 0; }
一念起,天涯咫尺; 一念灭,咫尺天涯。