Count(二维树状数组)

【bzoj1452】[JSOI2009]Count

Description

Input

Output

Sample Input

 

Sample Output

1
2
 

HINT

 

 

题解:对于每一个颜色建一个二维的树状数组O(c*logn*logm),试了试对每个颜色,每行建一个一维数组,超时了。。。O(c*n*logm)

若一维树状数组不会:http://www.cnblogs.com/haoabcd2010/p/6657393.html

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <string.h>
 4 
 5 using namespace std;
 6 #define MAXN 302
 7 
 8 int n,m;
 9 int G[MAXN][MAXN];
10 int tree[102][MAXN][MAXN]; // 颜色,行,列
11 
12 int lowbit(int x) {return x&(-x);}
13 
14 void update(int c,int x,int y,int add)
15 {
16     for(int i=x;i<=n;i+=lowbit(i))
17         for (int j=y;j<=m;j+=lowbit(j))
18             tree[c][i][j]+=add;
19 }
20 
21 int getsum(int c,int x,int y)
22 {
23     int ans =0;
24     for (int i=x;i>0;i-=lowbit(i))
25         for (int j=y;j>0;j-=lowbit(j))
26             ans += tree[c][i][j];
27     return ans;
28 }
29 
30 int main()
31 {
32     scanf("%d%d",&n,&m);
33     for (int i=1;i<=n;i++)
34         for (int j=1;j<=m;j++)
35         scanf("%d",&G[i][j]);
36 
37     for (int i=1;i<=n;i++)
38         for (int j=1;j<=m;j++)
39         update(G[i][j],i,j,1);
40 
41     int q;
42     scanf("%d",&q);
43     while (q--)
44     {
45         int op;
46         scanf("%d",&op);
47         if (op==1)
48         {
49             int x,y,c;
50             scanf("%d%d%d",&x,&y,&c);
51             update(c,x,y,1);//c颜色x,y +1
52             update(G[x][y],x,y,-1);//原来颜色xy -1
53             G[x][y]=c;
54         }
55         if (op==2)
56         {
57             int x1,x2,y1,y2,c;
58             scanf("%d%d%d%d%d",&x1,&x2,&y1,&y2,&c);
59             int ans = getsum(c,x2,y2)+getsum(c,x1-1,y1-1);   //c 颜色 i行y1-y2;
60             ans -= getsum(c,x1-1,y2);
61             ans -= getsum(c,x2,y1-1);
62             printf("%d\n",ans);
63         }
64     }
65     return 0;
66 }
View Code

 

 

 

 

posted @ 2017-04-03 18:30  happy_codes  阅读(149)  评论(0编辑  收藏  举报