library

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

View the Project on GitHub matumoto1234/library

:warning: math/segment-sieve.hpp

Depends on

Code

#pragma once

#include "./base.hpp"

#include <cassert>
#include <cmath>
#include <numeric>
#include <vector>

namespace matumoto {
  class SegmentSieve {
    ll l, r, sqrt_r;
    vector<int> small_sieve;
    vector<vector<ll>> large_sieve;
    vector<ll> aux; // aux[i] := large_sieve[i] の素因数の積

  public:
    SegmentSieve(ll l, ll r): l(l), r(r), sqrt_r(sqrt(r) + 1) {
      small_sieve.resize(sqrt_r);
      iota(small_sieve.begin(), small_sieve.end(), 0);
      large_sieve.resize(r - l);
      aux.assign(r - l, 1);

      for (ll i = 2; i * i < r; i++) {
        if (small_sieve[i] < i)
          continue;

        small_sieve[i] = i;
        for (ll j = i * i; j < sqrt_r; j += i) {
          if (small_sieve[j] == j)
            small_sieve[j] = i;
        }

        ll begin = (l + i - 1) / i * i;

        for (ll j = begin; j < r; j += i) {
          ll k = j;
          do {
            // aux[j - l] > sqrt_r ?
            if (aux[j - l] * aux[j - l] > r)
              break;

            large_sieve[j - l].push_back(i);
            aux[j - l] *= i;
            k /= i;
          } while (k % i == 0);
        }
      }
    }

    vector<ll> factor(ll n) {
      assert(l <= n and n < r);

      vector<ll> res = large_sieve[n - l];
      n /= aux[n - l];

      if (n >= sqrt_r) {
        res.push_back(n);
        return res;
      }

      while (n > 1) {
        res.push_back(small_sieve[n]);
        n /= small_sieve[n];
      }

      return res;
    }
  };
}; // namespace matumoto
#line 2 "math/segment-sieve.hpp"

#line 2 "math/base.hpp"

namespace matumoto {
  using namespace std;
  using ll = long long;
} // namespace matumoto
#line 4 "math/segment-sieve.hpp"

#include <cassert>
#include <cmath>
#include <numeric>
#include <vector>

namespace matumoto {
  class SegmentSieve {
    ll l, r, sqrt_r;
    vector<int> small_sieve;
    vector<vector<ll>> large_sieve;
    vector<ll> aux; // aux[i] := large_sieve[i] の素因数の積

  public:
    SegmentSieve(ll l, ll r): l(l), r(r), sqrt_r(sqrt(r) + 1) {
      small_sieve.resize(sqrt_r);
      iota(small_sieve.begin(), small_sieve.end(), 0);
      large_sieve.resize(r - l);
      aux.assign(r - l, 1);

      for (ll i = 2; i * i < r; i++) {
        if (small_sieve[i] < i)
          continue;

        small_sieve[i] = i;
        for (ll j = i * i; j < sqrt_r; j += i) {
          if (small_sieve[j] == j)
            small_sieve[j] = i;
        }

        ll begin = (l + i - 1) / i * i;

        for (ll j = begin; j < r; j += i) {
          ll k = j;
          do {
            // aux[j - l] > sqrt_r ?
            if (aux[j - l] * aux[j - l] > r)
              break;

            large_sieve[j - l].push_back(i);
            aux[j - l] *= i;
            k /= i;
          } while (k % i == 0);
        }
      }
    }

    vector<ll> factor(ll n) {
      assert(l <= n and n < r);

      vector<ll> res = large_sieve[n - l];
      n /= aux[n - l];

      if (n >= sqrt_r) {
        res.push_back(n);
        return res;
      }

      while (n > 1) {
        res.push_back(small_sieve[n]);
        n /= small_sieve[n];
      }

      return res;
    }
  };
}; // namespace matumoto
Back to top page