【BZOJ-1452】Count 树状数组 套 树状数组
1452: [JSOI2009]Count
Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 1769 Solved: 1059
[Submit][Status][Discuss]
Description
Input
Output
Sample Input
Sample Output
1
2
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系列....
——It's a lonely path. Don't make it any lonelier than it has to be.