BZOJ 1452 Count(二维树状数组)
大水题。 建立100个二维树状数组,总复杂度就是O(qlognlogm).
# include <cstdio> # include <cstring> # include <cstdlib> # include <iostream> # include <vector> # include <queue> # include <stack> # include <map> # include <set> # include <cmath> # include <algorithm> using namespace std; # define lowbit(x) ((x)&(-x)) # define pi 3.1415926535 # define eps 1e-9 # define MOD 100000007 # define INF 1000000000 # define mem(a,b) memset(a,b,sizeof(a)) # define FOR(i,a,n) for(int i=a; i<=n; ++i) # define FO(i,a,n) for(int i=a; i<n; ++i) # define bug puts("H"); # define lch p<<1,l,mid # define rch p<<1|1,mid+1,r # define mp make_pair # define pb push_back typedef pair<int,int> PII; typedef vector<int> VI; # pragma comment(linker, "/STACK:1024000000,1024000000") typedef long long LL; int Scan() { int res=0, flag=0; char ch; if((ch=getchar())=='-') flag=1; else if(ch>='0'&&ch<='9') res=ch-'0'; while((ch=getchar())>='0'&&ch<='9') res=res*10+(ch-'0'); return flag?-res:res; } void Out(int a) { if(a<0) {putchar('-'); a=-a;} if(a>=10) Out(a/10); putchar(a%10+'0'); } const int N=305; //Code begin... int tree[101][N][N], a[N][N], n, m; void add(int x, int i, int j, int val){ while (i<=n) { int k=j; while (k<=m) tree[x][i][k]+=val, k+=lowbit(k); i+=lowbit(i); } } int query(int x, int i, int j){ int res=0; while (i) { int k=j; while (k) res+=tree[x][i][k], k-=lowbit(k); i-=lowbit(i); } return res; } int main () { int Q, flag, x1, y1, x2, y2, c; n=Scan(); m=Scan(); FOR(i,1,n) FOR(j,1,m) { a[i][j]=Scan(); add(a[i][j],i,j,1); } Q=Scan(); while (Q--) { flag=Scan(); if (flag==1) { x1=Scan(); y1=Scan(); c=Scan(); add(a[x1][y1],x1,y1,-1); add(c,x1,y1,1); a[x1][y1]=c; } else { x1=Scan(); x2=Scan(); y1=Scan(); y2=Scan(); c=Scan(); printf("%d\n",query(c,x2,y2)-query(c,x2,y1-1)-query(c,x1-1,y2)+query(c,x1-1,y1-1)); } } return 0; }