diff --git a/algorithms/structure/bit.cpp b/algorithms/structure/bit.cpp
index ba8e8d3a6891eba186cc0a64db48de81cb3314ae..3b20716fae8ea4ed35d09a96471f709b5ded8ddf 100644
--- a/algorithms/structure/bit.cpp
+++ b/algorithms/structure/bit.cpp
@@ -9,11 +9,7 @@ struct BIT {
   int N;
   vector<int> tree;
 
-  BIT(int N) : 
-    N(N), tree(N) 
-  { init(); }
-
-  void init() { fill(all(tree), 0); }
+  BIT(int N) : N(N), tree(N, 0) {}
 
   int query(int idx) {
     int sum = 0;
diff --git a/algorithms/structure/bit2d.cpp b/algorithms/structure/bit2d.cpp
index 8a71df59333a13aa988fa0324353de6de83a363a..e02ba49c632e3c06548e45cf84eb26fa8d595549 100644
--- a/algorithms/structure/bit2d.cpp
+++ b/algorithms/structure/bit2d.cpp
@@ -11,14 +11,8 @@ struct BIT2D {
   int N, M;
   vector<vector<int>> tree;
 
-  BIT2D(int N, int M) :
-    N(N), M(M), tree(N, vector<int>(M))
-  { init(); }
-
-  void init() {
-    for (auto &i : tree)
-      fill(all(i), 0);
-  }
+  BIT2D(int N, int M) : N(N), M(M), 
+    tree(N, vector<int>(M, 0)) {}
 
   int query(int idx, int idy) {
     int sum = 0;
diff --git a/algorithms/structure/lazy_segment_tree.cpp b/algorithms/structure/lazy_segment_tree.cpp
index e2d45decd5e5c917ffed8fc205a42954b8ff7bde..758c47dc43f69c0f6e827527901156766c233d27 100644
--- a/algorithms/structure/lazy_segment_tree.cpp
+++ b/algorithms/structure/lazy_segment_tree.cpp
@@ -15,16 +15,14 @@
 
 int N;
 
-template <typename T>
+template <typename T, class F = function<T(const T&, const T&)>>
 struct LazySegmentTree {
-  using func = function<T(T,T)>;
-
-  func op;
+  F func;
   T id = T();
   vector<T> tree, lazy;
 
-  LazySegmentTree(func op) : 
-    op(op), tree(MAX*4, 0), lazy(MAX*4, 0) {}
+  LazySegmentTree(F func) : 
+    func(func), tree(MAX*4, 0), lazy(MAX*4, 0) {}
 
   void build(const vector<T> &v, 
       int node = 1, int l = 0, int r = N - 1) 
@@ -37,7 +35,7 @@ struct LazySegmentTree {
       int m = (l + r) / 2;
       build(v, left(node), l, m);
       build(v, right(node), m + 1, r);
-      tree[node] = op(tree[left(node)], tree[right(node)]);
+      tree[node] = func(tree[left(node)], tree[right(node)]);
     }
   }
 
@@ -66,7 +64,7 @@ struct LazySegmentTree {
       int m = (l + r) / 2;
       update(i, j, val, left(node), l, m);
       update(i, j, val, right(node), m + 1, r);
-      tree[node] = op(tree[left(node)], tree[right(node)]);
+      tree[node] = func(tree[left(node)], tree[right(node)]);
     }
   }
 
@@ -84,6 +82,6 @@ struct LazySegmentTree {
     int m = (l + r) / 2;
     T q1 = query(i, j, left(node), l, m);
     T q2 = query(i, j, right(node), m + 1, r);
-    return op(q1, q2);
+    return func(q1, q2);
   }
 };
diff --git a/algorithms/structure/segment_tree.cpp b/algorithms/structure/segment_tree.cpp
index 50727c5142881ff093d53b7881ef0b70efb59f44..5ae64d7e8dfb4a344d4ae4e6745605b70e48d75d 100644
--- a/algorithms/structure/segment_tree.cpp
+++ b/algorithms/structure/segment_tree.cpp
@@ -14,16 +14,13 @@
 
 int N;
 
-template <typename T>
+template <typename T, class F = function<T(const T&, const T&)>>
 struct SegmentTree {
-  using func = function<T(T,T)>;
-
-  func op;
+  F func;
   T ident = T();
   vector<T> tree;
 
-  SegmentTree(func op) : 
-    op(op), tree(MAX*4) {}
+  SegmentTree(F &func) : func(func), tree(MAX*4) {}
 
   void build(const vector<T> &v, 
       int node = 1, int l = 0, int r = N - 1) 
@@ -37,7 +34,7 @@ struct SegmentTree {
       int m = (l + r) / 2;
       build(v, left(node), l, m);
       build(v, right(node), m + 1, r);
-      tree[node] = op(tree[left(node)], tree[right(node)]);
+      tree[node] = func(tree[left(node)], tree[right(node)]);
     }
   }
 
@@ -53,7 +50,7 @@ struct SegmentTree {
       int m = (l + r) / 2;
       update(i, val, left(node), l, m);
       update(i, val, right(node), m + 1, r);
-      tree[node] = op(tree[left(node)], tree[right(node)]);
+      tree[node] = func(tree[left(node)], tree[right(node)]);
     }
   }
 
@@ -69,6 +66,6 @@ struct SegmentTree {
     int m = (l + r) / 2;
     T q1 = query(i, j, left(node), l, m);
     T q2 = query(i, j, right(node), m + 1, r);
-    return op(q1, q2);
+    return func(q1, q2);
   }
 };
diff --git a/algorithms/structure/segment_tree_2d.cpp b/algorithms/structure/segment_tree_2d.cpp
index 47818c79664425166e1a1210c867a07ddc6601be..c39c43711a246ab177bca506c8416143c80fe00c 100644
--- a/algorithms/structure/segment_tree_2d.cpp
+++ b/algorithms/structure/segment_tree_2d.cpp
@@ -14,19 +14,17 @@
 
 int N, M;
 
-template<typename T>
+template<typename T, class F = function<T(const T&, const T&)>>
 struct SegmentTree2D {
-  using func = function<T(T,T)>;
   using matrix<T> = vector<vector<T>>;
 
-  T id;
-  func op;
+  F func;
+  T id = T();
   matrix<T> tree;
 
-  SegmentTree2D(matrix<T> &mat, func op, T id = T()) :
+  SegmentTree2D(F func) :
     tree(4*MAX, vector<T>(4*MAX, 0)),
-    op(op), id(id)
-  { build(mat); }
+    func(func) {}
 
   void build_row(const matrix<T> &mat, 
       int ni, int li, int ri,
@@ -36,12 +34,12 @@ struct SegmentTree2D {
       if (li == ri) 
         tree[ni][nj] = mat[li][lj];
       else 
-        tree[ni][nj] = op(tree[left(ni)][nj], tree[right(ni)][nj]);
+        tree[ni][nj] = func(tree[left(ni)][nj], tree[right(ni)][nj]);
     } else {
       int m = (lj + rj) / 2;
       build_row(mat, ni, li, ri, left(nj), lj, m);
       build_row(mat, ni, li, ri, right(nj), m+1, rj);
-      tree[ni][nj] = op(tree[ni][left(nj)], tree[ni][right(nj)]);
+      tree[ni][nj] = func(tree[ni][left(nj)], tree[ni][right(nj)]);
     }
   }
 
@@ -67,7 +65,7 @@ struct SegmentTree2D {
     int m = (lj + rj) / 2;
     T q1 = query_row(j1, j2, i, left(nj), lj, m);
     T q2 = query_row(j1, j2, i, right(nj), m + 1, rj);
-    return op(q1, q2);
+    return func(q1, q2);
   }
 
   T query(int i1, int j1, int i2, int j2,
@@ -81,7 +79,7 @@ struct SegmentTree2D {
     int m = (li + ri) / 2;
     T q1 = query(i1, j1, i2, j2, left(ni), li, m);
     T q2 = query(i1, j1, i2, j2, right(ni), m + 1, ri);
-    return op(q1, q2);
+    return func(q1, q2);
   }
 
   void update_row(int i, int j, T val,
@@ -94,12 +92,12 @@ struct SegmentTree2D {
       if (li == ri) 
         tree[ni][nj] = val;
       else 
-        tree[ni][nj] = op(tree[left(ni)][nj], tree[right(ni)][nj]);
+        tree[ni][nj] = func(tree[left(ni)][nj], tree[right(ni)][nj]);
     } else {
       int m = (lj + rj) / 2;
       update_row(i, j, val, ni, li, ri, left(nj), lj, m);
       update_row(i, j, val, ni, li, ri, right(nj), m+1, rj);
-      tree[ni][nj] = op(tree[ni][left(nj)], tree[ni][right(nj)]);
+      tree[ni][nj] = func(tree[ni][left(nj)], tree[ni][right(nj)]);
     }
   }
 
@@ -113,6 +111,7 @@ struct SegmentTree2D {
       update(i, j, val, left(ni), li, m);
       update(i, j, val, right(ni), m+1, ri);
     }
+
     update_row(i, j, val, ni, li, ri);
   }
 };