アットウィキロゴ


区間更新区間最小

遅延セグ木で区間に対しての更新に対応

+ ソースコード
  1. // 区間更新、区間最小の遅延セグメントツリー
  2. struct RMQRUQ {
  3. int n;
  4. vector<int> dat, lazy;
  5.  
  6. RMQRUQ(){}
  7. RMQRUQ(int n_) {
  8. n = 1; while(n < n_) n *= 2;
  9. dat.assign(n*2, INT_MAX);
  10. lazy.assign(n*2, INT_MAX);
  11. }
  12.  
  13. void eval(int len, int k) {
  14. if(lazy[k] == INT_MAX) return;
  15. if(k*2+1 < n*2-1) {
  16. lazy[2*k+1] = lazy[k];
  17. lazy[2*k+2] = lazy[k];
  18. }
  19. dat[k] = lazy[k];
  20. lazy[k] = INT_MAX;
  21. }
  22.  
  23. // [a, b)
  24. ll update(int a, int b, ll x, int k, int l, int r) {
  25. eval(r-l, k);
  26. if(b <= l || r <= a) return dat[k];
  27. if(a <= l && r <= b) {
  28. lazy[k] = x;
  29. return lazy[k];
  30. }
  31. return dat[k] = min(update(a, b, x, 2*k+1, l, (l+r)/2), update(a, b, x, 2*k+2, (l+r)/2, r));
  32. }
  33. ll update(int a, int b, ll x) { return update(a, b, x, 0, 0, n); }
  34.  
  35. // [a, b)
  36. ll query(int a, int b, int k, int l, int r) {
  37. eval(r-l, k);
  38. if(b <= l || r <= a) return INT_MAX;
  39. if(a <= l && r <= b) return dat[k];
  40. ll vl = query(a, b, 2*k+1, l, (l+r)/2);
  41. ll vr = query(a, b, 2*k+2, (l+r)/2, r);
  42. return min(vl, vr);
  43. }
  44. ll query(int a, int b) { return query(a, b, 0, 0, n); }
  45. };
  46.  

区間加算区間和


+ ソースコード
  1. // 区間加算区間和
  2. struct RSQRAQ {
  3. int n;
  4. vector<ll> dat, lazy;
  5.  
  6. RSQRAQ(){}
  7. RSQRAQ(int n_) {
  8. n = 1; while(n < n_) n *= 2;
  9. dat.assign(n*2, 0);
  10. lazy.assign(n*2, 0);
  11. }
  12.  
  13. void eval(int len, int k) {
  14. if(lazy[k] == 0) return;
  15. if(k*2+1 < n*2-1) {
  16. lazy[2*k+1] += lazy[k];
  17. lazy[2*k+2] += lazy[k];
  18. }
  19. dat[k] += lazy[k]*len;
  20. lazy[k] = 0;
  21. }
  22.  
  23. // [a, b)
  24. ll update(int a, int b, ll x, int k, int l, int r) {
  25. eval(r-l, k);
  26. if(b <= l || r <= a) return dat[k];
  27. if(a <= l && r <= b) {
  28. lazy[k] += x;
  29. return dat[k] + lazy[k]*(r-l);
  30. }
  31. return dat[k] = update(a, b, x, 2*k+1, l, (l+r)/2) + update(a, b, x, 2*k+2, (l+r)/2, r);
  32. }
  33. ll update(int a, int b, ll x) { return update(a, b, x, 0, 0, n); }
  34.  
  35. // [a, b)
  36. ll query(int a, int b, int k, int l, int r) {
  37. eval(r-l, k);
  38. if(b <= l || r <= a) return 0;
  39. if(a <= l && r <= b) return dat[k];
  40. ll vl = query(a, b, 2*k+1, l, (l+r)/2);
  41. ll vr = query(a, b, 2*k+2, (l+r)/2, r);
  42. return vl + vr;
  43. }
  44. ll query(int a, int b) { return query(a, b, 0, 0, n); }
  45. };

starrysky木


+ ソースコード
  1. // 区間加算、区間最大のstarrysky木
  2. struct starrysky {
  3. int n;
  4. const int init_ = 0;
  5. VI lazym, lazya;
  6. starrysky(){}
  7. starrysky(int n_) {init(n_);}
  8. void init(int n_) {
  9. n = 1; while(n<n_) n *= 2;
  10. lazym.assign(2*n-1, init_);
  11. lazya.assign(2*n-1, 0);
  12. }
  13. // [a, b)
  14. void add(int a, int b, int x) {add(a, b, x, 0, 0, n);}
  15. void add(int a, int b, int x, int k, int l, int r) {
  16. if(r <= a || b <= l) return;
  17. if(a <= l && r <= b) lazya[k] += x;
  18. else {
  19. add(a, b, x, k*2+1, l, (l+r)/2);
  20. add(a, b, x, k*2+2, (l+r)/2, r);
  21. lazym[k] = max(lazym[k*2+1]+lazya[k*2+1],
  22. lazym[k*2+2]+lazya[k+2+2]);
  23. }
  24. }
  25. // [a, b)
  26. int query(int a, int b) {return query(a, b, 0, 0, n);}
  27. int query(int a, int b, int k, int l, int r) {
  28. if(r <= a || b <= l) return init_;
  29. if(a <= l && r <= b) return lazym[k] + lazya[k];
  30. int vl = query(a, b, k*2+1, l, (l+r)/2),
  31. vr = query(a, b, k*2+2, (l+r)/2, r);
  32. return max(vl, vr)+lazya[k];
  33. }
  34. };
  35.  
最終更新:2018年02月13日 22:23