luckYrat's library.

This documentation is automatically generated by competitive-verifier/competitive-verifier


:warning: cpp/data-structure/segment-tree/2d-segment-tree.cpp

Required by

Code

struct Segtree{
  int N;
  vector<long long> val;
  void init(int n){
    N = 1;
    while(N < n) N *= 2;
    val = vector<long long>(N*2, 0); 
  }

  void update(int i, long long v){
    i += N;
    val[i] += v;
    while(i > 1){
      i /= 2;
      val[i] = val[i*2] + val[i*2+1];
    }
  }

  long long get(int x, int y, int k, int l, int r){
    if(r <= x || y <= l)return 0;
    if(x <= l && r <= y)return val[k];

    auto a = get(x, y, k*2, l, (l+r)/2);
    auto b = get(x, y, k*2+1, (l+r)/2, r);
    return a+b;
  }
  long long get(int x, int y){
    return get(x, y, 1, 0, N);
  }
};

struct SegtreeOnSegtree{
  int N;
  vector<Segtree> st;
  vector<vector<int>> index;

  void init(vector<vector<int>> &v){
    int n = v.size();
    N = 1;
    while(N < n) N *= 2;
    index.resize(N * 2);
    for(int i = 0; n > i; i++){
      for(int j = 0; (int)v[i].size() > j; j++){
        index[i+N].push_back(v[i][j]);
      }
    }
    for(int i = N*2-1; 1 <= i; i--){
      sort(index[i].begin(),index[i].end());
      index[i].erase(unique(index[i].begin(),index[i].end()), index[i].end());
      for(int j = 0; (int)index[i].size() > j; j++){
        index[i/2].push_back(index[i][j]);
      }
    }
    st.resize(2*N);
    for(int i = 1; 2*N > i; i++)st[i].init(index[i].size());
  }

  void update(int x,int y, long long v){//x: compressed, y: uncompressed
    assert(x < N);
    x += N;
    while(x) {
      int yy = lower_bound(index[x].begin(),index[x].end(),y) - index[x].begin();
      assert(yy != (int)index[x].size());
      assert(y == index[x][yy]);
      st[x].update(yy,v);
      x /= 2;
    }
  }

  long long get(int sx, int tx, int sy, int ty, int k, int l, int r){
    assert(k < N*2);
    assert(l < r);
    if(r <= sx || tx <= l)return 0;
    if(sx <= l && r <= tx){
      //TODO: is it correct?
      int syy = lower_bound(index[k].begin(), index[k].end(), sy) - index[k].begin();
      int tyy = lower_bound(index[k].begin(), index[k].end(), ty) - index[k].begin();
      return st[k].get(syy, tyy);
    }
    int ce = (l+r)/2;
    long long le = get(sx, tx, sy, ty, k * 2, l, ce);
    long long ri = get(sx, tx, sy, ty, k * 2 + 1, ce, r);
    return le+ri;
  }

  long long get(int sx, int tx, int sy, int ty){
    return get(sx, tx, sy, ty, 1, 0, N);
  }
};
#line 1 "cpp/data-structure/segment-tree/2d-segment-tree.cpp"
struct Segtree{
  int N;
  vector<long long> val;
  void init(int n){
    N = 1;
    while(N < n) N *= 2;
    val = vector<long long>(N*2, 0); 
  }

  void update(int i, long long v){
    i += N;
    val[i] += v;
    while(i > 1){
      i /= 2;
      val[i] = val[i*2] + val[i*2+1];
    }
  }

  long long get(int x, int y, int k, int l, int r){
    if(r <= x || y <= l)return 0;
    if(x <= l && r <= y)return val[k];

    auto a = get(x, y, k*2, l, (l+r)/2);
    auto b = get(x, y, k*2+1, (l+r)/2, r);
    return a+b;
  }
  long long get(int x, int y){
    return get(x, y, 1, 0, N);
  }
};

struct SegtreeOnSegtree{
  int N;
  vector<Segtree> st;
  vector<vector<int>> index;

  void init(vector<vector<int>> &v){
    int n = v.size();
    N = 1;
    while(N < n) N *= 2;
    index.resize(N * 2);
    for(int i = 0; n > i; i++){
      for(int j = 0; (int)v[i].size() > j; j++){
        index[i+N].push_back(v[i][j]);
      }
    }
    for(int i = N*2-1; 1 <= i; i--){
      sort(index[i].begin(),index[i].end());
      index[i].erase(unique(index[i].begin(),index[i].end()), index[i].end());
      for(int j = 0; (int)index[i].size() > j; j++){
        index[i/2].push_back(index[i][j]);
      }
    }
    st.resize(2*N);
    for(int i = 1; 2*N > i; i++)st[i].init(index[i].size());
  }

  void update(int x,int y, long long v){//x: compressed, y: uncompressed
    assert(x < N);
    x += N;
    while(x) {
      int yy = lower_bound(index[x].begin(),index[x].end(),y) - index[x].begin();
      assert(yy != (int)index[x].size());
      assert(y == index[x][yy]);
      st[x].update(yy,v);
      x /= 2;
    }
  }

  long long get(int sx, int tx, int sy, int ty, int k, int l, int r){
    assert(k < N*2);
    assert(l < r);
    if(r <= sx || tx <= l)return 0;
    if(sx <= l && r <= tx){
      //TODO: is it correct?
      int syy = lower_bound(index[k].begin(), index[k].end(), sy) - index[k].begin();
      int tyy = lower_bound(index[k].begin(), index[k].end(), ty) - index[k].begin();
      return st[k].get(syy, tyy);
    }
    int ce = (l+r)/2;
    long long le = get(sx, tx, sy, ty, k * 2, l, ce);
    long long ri = get(sx, tx, sy, ty, k * 2 + 1, ce, r);
    return le+ri;
  }

  long long get(int sx, int tx, int sy, int ty){
    return get(sx, tx, sy, ty, 1, 0, N);
  }
};
Back to top page