1
1
2
2
/* *
3
3
4
- 2D BIT
4
+ 2D Fenwick Tree
5
+ ===============
6
+
7
+ Description
8
+ -----------
9
+
10
+ A data structure to quickly do the following -
11
+ 1 . Point Update
12
+ 2 . Prefix Sum Array Update
13
+
14
+ Operations
15
+ ----------
16
+ - Add value to an index : O( (logN)^2 )
17
+ - Calculate Prefix Sum upto an index : O( (logN)^2 )
5
18
6
19
**/
7
20
@@ -13,108 +26,155 @@ using namespace std;
13
26
#define LL long long
14
27
#define PII pair<int ,int >
15
28
#define PLL pair<LL,LL>
16
- #define MP make_pair
17
29
#define F first
18
30
#define S second
19
- #define INF INT_MAX
31
+
32
+ #define ALL (x ) (x).begin(), (x).end()
33
+ #define READ freopen (" alu.txt" , " r" , stdin)
34
+ #define WRITE freopen (" vorta.txt" , " w" , stdout)
35
+
36
+ #ifndef ONLINE_JUDGE
37
+ #define DBG (x ) cout << __LINE__ << " says: " << #x << " = " << (x) << endl
38
+ #else
39
+ #define DBG (x )
40
+ #define endl " \n "
41
+ #endif
42
+
43
+ template <class T1 , class T2 >
44
+ ostream &operator <<(ostream &os, pair<T1,T2>&p);
45
+ template <class T >
46
+ ostream &operator <<(ostream &os, vector<T>&v);
47
+ template <class T >
48
+ ostream &operator <<(ostream &os, set<T>&v);
20
49
21
50
inline void optimizeIO ()
22
51
{
23
52
ios_base::sync_with_stdio (false );
24
53
cin.tie (NULL );
25
54
}
26
55
27
- const int nmax = 1024 +5 ;
28
- const LL LINF = 1e17 ;
56
+ const int nmax = 2e5 +7 ;
29
57
30
- string to_str (LL x)
31
- {
32
- stringstream ss;
33
- ss<<x;
34
- return ss.str ();
35
- }
36
-
37
- int n;
38
- int ara[nmax][nmax];
58
+ struct Fenwick2D {
39
59
60
+ vector<vector<LL>>BIT;
61
+ int R,C;
40
62
63
+ Fenwick2D (int r,int c) : BIT(r+1 ,vector<LL>(c+1 ,0 )) , R(r) , C(c) {}
41
64
42
- /* * 2D BIT / FENWICK TREE **/
43
- /* ** 1 based indexing ***/
65
+ inline int LSB (int x) {return x&(-x);} // / find the number with first bit set
44
66
45
- int BIT[nmax][nmax];
46
- inline int lowbit (int x)
47
- {
48
- return x&(-x);
49
- }
67
+ // / POINT update : adds val to index (x,y)
68
+ void add (int x,int y,LL val)
69
+ {
70
+ for (int i = x ; i<=R ; i += LSB (i))
71
+ for (int j = y ; j<=C ; j += LSB (j))
72
+ BIT[i][j] += val;
73
+ }
50
74
51
- inline void update (int x,int y,int val) /* * POINT update , adds to the current value . Point = {x,y} **/
52
- {
53
- for (int i = x; i <= n; i += lowbit (i))
54
- for (int j = y; j <= n; j += lowbit (j))
55
- BIT[i][j] += val;
56
- }
75
+ // / prefix sum of [(1,1) , (x,y)] square
76
+ LL pref (int x,int y)
77
+ {
78
+ LL sum = 0 ;
57
79
58
- inline int query (int x,int y) /* * RANGE Sum . Range = [{1,1} , {x,y}] **/
59
- {
60
- int sum = 0 ;
61
- for (int i = x; i > 0 ; i -= lowbit (i))
62
- for (int j = y; j > 0 ; j -= lowbit (j))
80
+ for (int i = x ; i>0 ; i -= LSB (i))
81
+ for (int j = y ; j>0 ; j -= LSB (j))
63
82
sum += BIT[i][j];
64
83
65
- return sum;
66
- }
67
-
68
- int main ()
69
- {
70
- // freopen("OUT.txt","w",stdout);
84
+ return sum;
85
+ }
71
86
72
- n = 3 ;
87
+ // / sum of [(xl,yl) , (xh,yh)] square
88
+ LL sum (int xl,int yl,int xh,int yh)
89
+ {
90
+ LL v1 = pref (xh, yh);
91
+ LL v2 = pref (xh, yl-1 );
92
+ LL v3 = pref (xl-1 , yh);
93
+ LL v4 = pref (xl-1 , yl-1 );
94
+ return v1 - v2 - v3 + v4;
95
+ }
73
96
74
- int val = 0 ;
75
- for (int i=1 ; i<=n; i++)
76
- for (int j=1 ; j<=n; j++)
97
+ void debug ()
98
+ {
99
+ cout<<" Prefix Sum Array :\n " ;
100
+ for (int i=1 ; i<=R; i++)
77
101
{
78
- // cin>>val;
79
- val++;
80
- ara[i][j] = val;
81
- update (i,j,ara[i][j]); /* * Initial Update **/
102
+ for (int j=1 ; j<=C; j++)
103
+ cout<<pref (i,j)<<" " ;
104
+ cout<<endl;
82
105
}
106
+ cout<<endl;
107
+ }
108
+ };
83
109
84
110
85
- int query_count;
86
- cin>>query_count;
111
+ int main ()
112
+ {
113
+ optimizeIO ();
114
+
115
+ int r,c,q;
116
+ cin>>r>>c>>q;
87
117
88
- while (query_count--)
118
+ Fenwick2D f (r,c);
119
+
120
+ for (int i=1 ;i<=q;i++)
89
121
{
122
+ f.debug ();
123
+
90
124
int type;
91
125
cin>>type;
92
126
93
127
if (type==1 )
94
128
{
95
- /* * Add val to { x,y} * */
96
- int x,y, val;
129
+ int x,y;
130
+ LL val;
97
131
cin>>x>>y>>val;
98
132
99
- update (x,y,val);
133
+ f. add (x,y,val); // / point update
100
134
}
101
- else
135
+ else if (type== 2 )
102
136
{
103
- /* * Sum of Range = [{x1,y1} , {x2,y2}] **/
104
137
int x1,y1 ,x2,y2;
105
138
cin>>x1>>y1 >>x2>>y2;
106
139
107
- int v1 = query (x2, y2);
108
- int v2 = query (x2, y1 -1 );
109
- int v3 = query (x1-1 , y2);
110
- int v4 = query (x1-1 , y1 -1 );
111
- int ans = v1 - v2 - v3 + v4;
112
- cout<<" Sum : " <<ans<<endl;
140
+ cout<<f.sum (x1,y1 ,x2,y2)<<endl; // / range sum
113
141
}
114
142
}
115
143
144
+ return 0 ;
145
+ }
116
146
147
+ /* *
148
+ 5 6 5
149
+ 2 2 2 4 5 1
150
+ **/
117
151
118
- return 0 ;
152
+ template <class T1 , class T2 >
153
+ ostream &operator <<(ostream &os, pair<T1,T2>&p)
154
+ {
155
+ os<<" {" <<p.first <<" , " <<p.second <<" } " ;
156
+ return os;
157
+ }
158
+ template <class T >
159
+ ostream &operator <<(ostream &os, vector<T>&v)
160
+ {
161
+ os<<" [ " ;
162
+ for (T i:v)
163
+ {
164
+ os<<i<<" " ;
165
+ }
166
+ os<<" ]" ;
167
+ return os;
119
168
}
120
169
170
+ template <class T >
171
+ ostream &operator <<(ostream &os, set<T>&v)
172
+ {
173
+ os<<" [ " ;
174
+ for (T i:v)
175
+ {
176
+ os<<i<<" " ;
177
+ }
178
+ os<<" ]" ;
179
+ return os;
180
+ }
0 commit comments