cpp-library

This documentation is automatically generated by online-judge-tools/verification-helper

View the Project on GitHub 9tc/cpp-library

:x: verify/LC-RangeAffineRangeSum.test.cpp

Depends on

Code

#define PROBLEM "https://judge.yosupo.jp/problem/range_affine_range_sum"

#include "../template/template.hpp"
#include "../data-structure/segment-tree/range-affine-range-sum-query.hpp"

int main(){
  int N, Q;
  cin >> N >> Q;
  VL a = input(N);

  RangeAffineRangeSumQuery<ll> rsq(N, 998244353);
  REP(i,N) rsq.set(i, a[i]);
  REP(i,Q){
    int t;
    cin >> t;
    if(t == 0){
      int l, r;
      ll b, c;
      cin >> l >> r >> b >> c;
      rsq.applyRange(l, r, {b, c});
    }else{
      int l, r;
      cin >> l >> r;
      cout << rsq.query(l, r) << endl;
    }
  }
}
#line 1 "verify/LC-RangeAffineRangeSum.test.cpp"
#define PROBLEM "https://judge.yosupo.jp/problem/range_affine_range_sum"

#line 1 "template/template.hpp"
#include<bits/stdc++.h>
using ll = long long;
#define REP(i, n) for(ll i = 0; (i) < ll(n); ++ (i))
#define FOR(i, m, n) for(ll i = (m); (i) <= ll(n); ++ (i))
#define REPR(i, n) for(ll i = ll(n) - 1; (i) >= 0; -- (i))
#define FORR(i, m, n) for(ll i = ll(n); (i) >= ll(m); -- (i))
#define ALL(x) x.begin(),x.end()

#define INF (int)1e9
#define LLINF (long long)1e18
#define MOD (int)(1e9+7)
#define MOD9 (int)998244353
#define PI 3.141592653589
#define PB push_back
#define F first
#define S second

#define YESNO(T) if(T){cout<<"YES"<<endl;}else{cout<<"NO"<<endl;}
#define yesno(T) if(T){cout<<"yes"<<endl;}else{cout<<"no"<<endl;}
#define YesNo(T) if(T){cout<<"Yes"<<endl;}else{cout<<"No"<<endl;}
#define Yes(T) {cout<<"Yes"<<endl; if(T) return 0;}
#define No(T) {cout <<"No"<<endl; if(T) return 0;}
#define YES(T) {cout<<"YES"<<endl; if(T) return 0;}
#define NO(T) {cout <<"NO"<<endl; if(T) return 0;}

#define Graph vector<vector<int> >
#define CostGraph vector<vector<pair<int,ll> > >
#define PII pair<int,int>
#define PLL pair<ll,ll>
#define VI vector<int>
#define VL vector<ll>
#define VVI vector<vector<int> >
#define VVL vector<vector<ll> >
#define VPII vector<pair<int,int> >
#define VPLL vector<pair<ll,ll> >

#define DDD fixed<<setprecision(10)
#define PAD setfill('0')<<right<<setw(8)

template <class T>
inline bool chmin(T &a, T b) {
  if(a > b){ a = b; return true;}
  return false;
}
template <class T>
inline bool chmax(T &a, T b) {
  if(a < b){a = b; return true;}
  return false;
}
struct input{
  int n;
  input() {}
  input(int n_) : n(n_){};
  template <class T>
  operator T(){
    T ret;
    std::cin >> ret;
    return ret;
  }
  template <class T>
  operator std::vector<T>() {
    std::vector<T> ret(n);
    REP(i,n) std::cin >> ret[i];
    return ret;
  }
};
template <class T>
inline void printVec(std::vector<T> v){
  REP(i,v.size()){
    if(i) std::cout << " ";
    std::cout << v[i];
  } std::cout << std::endl;
}

using namespace std;
#line 1 "data-structure/segment-tree/lazy-segment-tree.hpp"
template <typename T, typename E>
struct LazySegmentTree{
  using F = function<T(T, T)>;
  using G = function<T(T, E)>;
  using H = function<E(E, E)>;
  int n, sz, height;
  vector<T> data;
  vector<E> lazy;
  const F f;
  const G g;
  const H h;
  const T e;
  const E eLazy;

  inline void update(int k){
    data[k] = f(data[2 * k + 0], data[2 * k + 1]);
  }

  inline void all_apply(int k, const E &x) {
    data[k] = g(data[k], x);
    if(k < sz) lazy[k] = h(lazy[k], x);
  }

  inline void propagate(int k){
    if(lazy[k] != eLazy){
      all_apply(2 * k + 0, lazy[k]);
      all_apply(2 * k + 1, lazy[k]);
      lazy[k] = eLazy;
    }
  }

  // LazySegmentTree() = default;
  LazySegmentTree(int n, const F f, const G g, const H h, const T &e, const E &eLazy): n(n), f(f), g(g), h(h), e(e), eLazy(eLazy){
    sz = 1;
    height = 0;
    while(sz < n) sz <<= 1, ++height;
    data.assign(2 * sz, e);
    lazy.assign(2 * sz, eLazy);
  }

  void set(int k, const T &x){
    k += sz;
    for(int i = height; i > 0; --i) propagate(k >> i);
    data[k] = x;
    for(int i = 1; i <= height; ++i) update(k >> i);
  }

  T query(int l, int r){
    if(l >= r) return e;
    l += sz;
    r += sz;
    for(int i = height; i > 0; --i){
      if(((l >> i) << i) != l) propagate(l >> i);
      if(((r >> i) << i) != r) propagate((r - 1) >> i);
    }
    T lval = e, rval = e;
    for(; l < r; l >>= 1, r >>= 1){
      if(l & 1) lval = f(lval, data[l++]);
      if(r & 1) rval = f(data[--r], rval);
    }
    return f(lval, rval);
  }

  void apply(int k, const E &x){
    k += sz;
    for(int i = height; i > 0; --i) propagate(k >> i);
    data[k] = g(data[k], x);
    for(int i = 1; i <= height; ++i) update(k >> i);
  }

  void applyRange(int l, int r, const E &x){
    if(l >= r) return;
    l += sz;
    r += sz;
    for(int i = height; i > 0; --i){
      if(((l >> i) << i) != l) propagate(l >> i);
      if(((r >> i) << i) != r) propagate((r - 1) >> i);
    }

    int l2 = l, r2 = r;
    for(; l < r; l >>= 1, r >>= 1){
      if(l & 1) all_apply(l++, x);
      if(r & 1) all_apply(--r, x);
    }
    l = l2, r = r2;

    for(int i = 1; i <= height; ++i){
      if(((l >> i) << i) != l) update(l >> i);
      if(((r >> i) << i) != r) update((r - 1) >> i);
    }
  }

  template <typename C>
  int findFirst(int l, const C &check){
    if(l >= n) return n;
    l += sz;
    for(int i = height; i > 0; --i) propagate(l >> i);
    T sum = e;
    do{
      while((l & 1) == 0) l >>= 1;
      if(check(f(sum, data[l]))){
        while(l < sz) {
          propagate(l);
          l <<= 1;
          auto nxt = f(sum, data[l]);
          if(!check(nxt)){
            sum = nxt;
            ++l;
          }
        }
        return l + 1 - sz;
      }
      sum = f(sum, data[l++]);
    }while((l & -l) != l);
    return n;
  }

  template <typename C>
  int findLast(int r, const C &check){
    if(r <= 0) return -1;
    r += sz;
    for(int i = height; i > 0; --i) propagate((r - 1) >> i);
    T sum = e;
    do{
      --r;
      while(r > 1 and (r & 1)) r >>= 1;
      if(check(f(data[r], sum))){
        while(r < sz){
          propagate(r);
          r = (r << 1) + 1;
          auto nxt = f(data[r], sum);
          if(!check(nxt)){
            sum = nxt;
            --r;
          }
        }
        return r - sz;
      }
      sum = f(data[r], sum);
    }while((r & -r) != r);
    return -1;
  }
};
#line 2 "data-structure/segment-tree/range-affine-range-sum-query.hpp"
template <typename T>
struct RangeAffineRangeSumQuery{
  using P = pair<T,T>;

  int n;
  T mod;

  function<P(P,P)> f = [&](P a, P b)->P{
    return {(a.first + b.first) % mod, (a.second + b.second) % mod};
  };

  function<P(P,P)> g = [&](P a, P b)->P{
    return {(a.first * b.first + a.second * b.second) % mod, a.second % mod};
  };

  function<P(P,P)> h = [&](P a, P b)->P{
    return {a.first * b.first % mod, (a.second * b.first + b.second) % mod};
  };

  LazySegmentTree<P, P> seg;
  RangeAffineRangeSumQuery(int n, T mod): n(n), mod(mod), seg(n, f, g, h, P({0, 0}), P({1, 0})){

  }

  void set(int k, T &x){
    seg.set(k, {x, 1});
  }

  void applyRange(int l, int r, P p){
    seg.applyRange(l, r, p);
  }

  T query(int l, int r){
    return seg.query(l, r).first;
  }
};
#line 5 "verify/LC-RangeAffineRangeSum.test.cpp"

int main(){
  int N, Q;
  cin >> N >> Q;
  VL a = input(N);

  RangeAffineRangeSumQuery<ll> rsq(N, 998244353);
  REP(i,N) rsq.set(i, a[i]);
  REP(i,Q){
    int t;
    cin >> t;
    if(t == 0){
      int l, r;
      ll b, c;
      cin >> l >> r >> b >> c;
      rsq.applyRange(l, r, {b, c});
    }else{
      int l, r;
      cin >> l >> r;
      cout << rsq.query(l, r) << endl;
    }
  }
}
Back to top page