<commit_before>#define DEBUG 1
/**
 * File    : E.cpp
 * Author  : Kazune Takahashi
 * Created : 2/7/2020, 2:25:43 PM
 * Powered by Visual Studio Code
 */
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <chrono>
#include <cmath>
#include <complex>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <vector>
// ----- boost -----
#include <boost/rational.hpp>
#include <boost/multiprecision/cpp_int.hpp>
// ----- using directives and manipulations -----
using namespace std;
using boost::rational;
using boost::multiprecision::cpp_int;
using ll = long long;
template <typename T>
using max_heap = priority_queue<T>;
template <typename T>
using min_heap = priority_queue<T, vector<T>, greater<T>>;
// ----- constexpr for Mint and Combination -----
constexpr ll MOD{1000000007LL};
// constexpr ll MOD{998244353LL}; // be careful
constexpr ll MAX_SIZE{3000010LL};
// constexpr ll MAX_SIZE{30000010LL}; // if 10^7 is needed
// ----- ch_max and ch_min -----
template <typename T>
void ch_max(T &left, T right)
{
  if (left < right)
  {
    left = right;
  }
}
template <typename T>
void ch_min(T &left, T right)
{
  if (left > right)
  {
    left = right;
  }
}
// ----- Mint -----
template <ll MOD = MOD>
class Mint
{
public:
  ll x;
  Mint() : x{0LL} {}
  Mint(ll x) : x{(x % MOD + MOD) % MOD} {}
  Mint operator-() const { return x ? MOD - x : 0; }
  Mint &operator+=(const Mint &a)
  {
    if ((x += a.x) >= MOD)
    {
      x -= MOD;
    }
    return *this;
  }
  Mint &operator-=(const Mint &a) { return *this += -a; }
  Mint &operator++() { return *this += 1; }
  Mint &operator++(int)
  {
    Mint tmp{*this};
    ++*this;
    return tmp;
  }
  Mint &operator--() { return *this -= 1; }
  Mint &operator--(int)
  {
    Mint tmp{*this};
    --*this;
    return tmp;
  }
  Mint &operator*=(const Mint &a)
  {
    (x *= a.x) %= MOD;
    return *this;
  }
  Mint &operator/=(const Mint &a)
  {
    Mint b{a};
    return *this *= b.power(MOD - 2);
  }
  Mint operator+(const Mint &a) const { return Mint(*this) += a; }
  Mint operator-(const Mint &a) const { return Mint(*this) -= a; }
  Mint operator*(const Mint &a) const { return Mint(*this) *= a; }
  Mint operator/(const Mint &a) const { return Mint(*this) /= a; }
  bool operator<(const Mint &a) const { return x < a.x; }
  bool operator<=(const Mint &a) const { return x <= a.x; }
  bool operator>(const Mint &a) const { return x > a.x; }
  bool operator>=(const Mint &a) const { return x >= a.x; }
  bool operator==(const Mint &a) const { return x == a.x; }
  bool operator!=(const Mint &a) const { return !(*this == a); }
  const Mint power(ll N)
  {
    if (N == 0)
    {
      return 1;
    }
    else if (N % 2 == 1)
    {
      return *this * power(N - 1);
    }
    else
    {
      Mint half = power(N / 2);
      return half * half;
    }
  }
};
template <ll MOD>
Mint<MOD> operator+(ll lhs, const Mint<MOD> &rhs)
{
  return rhs + lhs;
}
template <ll MOD>
Mint<MOD> operator-(ll lhs, const Mint<MOD> &rhs)
{
  return -rhs + lhs;
}
template <ll MOD>
Mint<MOD> operator*(ll lhs, const Mint<MOD> &rhs)
{
  return rhs * lhs;
}
template <ll MOD>
Mint<MOD> operator/(ll lhs, const Mint<MOD> &rhs)
{
  return Mint<MOD>{lhs} / rhs;
}
template <ll MOD>
istream &operator>>(istream &stream, Mint<MOD> &a)
{
  return stream >> a.x;
}
template <ll MOD>
ostream &operator<<(ostream &stream, const Mint<MOD> &a)
{
  return stream << a.x;
}
// ----- Combination -----
template <ll MOD = MOD, ll MAX_SIZE = MAX_SIZE>
class Combination
{
public:
  vector<Mint<MOD>> inv, fact, factinv;
  Combination() : inv(MAX_SIZE), fact(MAX_SIZE), factinv(MAX_SIZE)
  {
    inv[1] = 1;
    for (auto i = 2LL; i < MAX_SIZE; i++)
    {
      inv[i] = (-inv[MOD % i]) * (MOD / i);
    }
    fact[0] = factinv[0] = 1;
    for (auto i = 1LL; i < MAX_SIZE; i++)
    {
      fact[i] = Mint<MOD>(i) * fact[i - 1];
      factinv[i] = inv[i] * factinv[i - 1];
    }
  }
  Mint<MOD> operator()(int n, int k)
  {
    if (n >= 0 && k >= 0 && n - k >= 0)
    {
      return fact[n] * factinv[k] * factinv[n - k];
    }
    return 0;
  }
  Mint<MOD> catalan(int x, int y)
  {
    return (*this)(x + y, y) - (*this)(x + y, y - 1);
  }
};
// ----- for C++14 -----
using mint = Mint<MOD>;
using combination = Combination<MOD, MAX_SIZE>;
template <typename T>
T gcd(T x, T y) { return y ? gcd(y, x % y) : x; }
template <typename T>
T lcm(T x, T y) { return x / gcd(x, y) * y; }
// ----- for C++17 -----
template <typename T>
int popcount(T x) // C++20
{
  int ans{0};
  while (x != 0)
  {
    ans += x & 1;
    x >>= 1;
  }
  return ans;
}
// ----- frequently used constexpr -----
// constexpr double epsilon{1e-10};
constexpr ll infty{1000000000000000LL};
// constexpr int dx[4] = {1, 0, -1, 0};
// constexpr int dy[4] = {0, 1, 0, -1};
// ----- Yes() and No() -----
void Yes()
{
  cout << "Yes" << endl;
  exit(0);
}
void No()
{
  cout << "No" << endl;
  exit(0);
}
// ----- main() -----

using Query = tuple<ll, ll>;

int main()
{
  ll N, M, L;
  cin >> N >> M >> L;
  vector<vector<ll>> D(N, vector<ll>(N, infty));
  for (auto i = 0; i < M; ++i)
  {
    ll A, B, C;
    cin >> A >> B >> C;
    --A;
    --B;
    D[A][B] = C;
    D[B][A] = C;
  }
  ll Q;
  cin >> Q;
  vector<Query> W(Q);
  for (auto i = 0; i < Q; ++i)
  {
    int s, t;
    cin >> s >> t;
    --s;
    --t;
    W.push_back(Query(s, t));
  }
  for (auto k = 0; k < N; ++k)
  {
    for (auto i = 0; i < N; ++i)
    {
      if (i == k)
      {
        continue;
      }
      for (auto j = 0; j < N; ++j)
      {
        if (i == j || j == k)
        {
          continue;
        }
        ch_min(D[i][j], D[i][k] + D[k][j]);
      }
    }
  }
#if DEBUG == 1
  for (auto i = 0; i < N; ++i)
  {
    for (auto j = 0; j < N; ++j)
    {
      cerr << "D[" << i << "][" << j << "] = " << D[i][j] << endl;
    }
  }
#endif
  vector<vector<ll>> E(N, vector<ll>(N, infty));
  for (auto i = 0; i < N; ++i)
  {
    for (auto j = 0; j < N; ++j)
    {
      if (D[i][j] <= L)
      {
        E[i][j] = 1;
      }
    }
  }
#if DEBUG == 1
  for (auto i = 0; i < N; ++i)
  {
    for (auto j = 0; j < N; ++j)
    {
      cerr << "E[" << i << "][" << j << "] = " << E[i][j] << endl;
    }
  }
#endif
  for (auto k = 0; k < N; ++k)
  {
    for (auto i = 0; i < N; ++i)
    {
      if (i == k)
      {
        continue;
      }
      for (auto j = 0; j < N; ++j)
      {
        if (i == j || j == k)
        {
          continue;
        }
        ch_min(E[i][j], E[i][k] + E[k][j]);
      }
    }
  }
#if DEBUG == 1
  for (auto i = 0; i < N; ++i)
  {
    for (auto j = 0; j < N; ++j)
    {
      cerr << "E[" << i << "][" << j << "] = " << E[i][j] << endl;
    }
  }
#endif
  for (auto i = 0; i < Q; ++i)
  {
    ll s, t;
    tie(s, t) = W[i];
#if DEBUG == 1
    cerr << "E[" << s << "][" << t << "] = " << E[s][t] << endl;
#endif
    cout << (E[s][t] < infty ? E[s][t] : -1) << endl;
  }
}
<commit_msg>tried E.cpp to 'E'<commit_after>#define DEBUG 1
/**
 * File    : E.cpp
 * Author  : Kazune Takahashi
 * Created : 2/7/2020, 2:25:43 PM
 * Powered by Visual Studio Code
 */
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <chrono>
#include <cmath>
#include <complex>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <vector>
// ----- boost -----
#include <boost/rational.hpp>
#include <boost/multiprecision/cpp_int.hpp>
// ----- using directives and manipulations -----
using namespace std;
using boost::rational;
using boost::multiprecision::cpp_int;
using ll = long long;
template <typename T>
using max_heap = priority_queue<T>;
template <typename T>
using min_heap = priority_queue<T, vector<T>, greater<T>>;
// ----- constexpr for Mint and Combination -----
constexpr ll MOD{1000000007LL};
// constexpr ll MOD{998244353LL}; // be careful
constexpr ll MAX_SIZE{3000010LL};
// constexpr ll MAX_SIZE{30000010LL}; // if 10^7 is needed
// ----- ch_max and ch_min -----
template <typename T>
void ch_max(T &left, T right)
{
  if (left < right)
  {
    left = right;
  }
}
template <typename T>
void ch_min(T &left, T right)
{
  if (left > right)
  {
    left = right;
  }
}
// ----- Mint -----
template <ll MOD = MOD>
class Mint
{
public:
  ll x;
  Mint() : x{0LL} {}
  Mint(ll x) : x{(x % MOD + MOD) % MOD} {}
  Mint operator-() const { return x ? MOD - x : 0; }
  Mint &operator+=(const Mint &a)
  {
    if ((x += a.x) >= MOD)
    {
      x -= MOD;
    }
    return *this;
  }
  Mint &operator-=(const Mint &a) { return *this += -a; }
  Mint &operator++() { return *this += 1; }
  Mint &operator++(int)
  {
    Mint tmp{*this};
    ++*this;
    return tmp;
  }
  Mint &operator--() { return *this -= 1; }
  Mint &operator--(int)
  {
    Mint tmp{*this};
    --*this;
    return tmp;
  }
  Mint &operator*=(const Mint &a)
  {
    (x *= a.x) %= MOD;
    return *this;
  }
  Mint &operator/=(const Mint &a)
  {
    Mint b{a};
    return *this *= b.power(MOD - 2);
  }
  Mint operator+(const Mint &a) const { return Mint(*this) += a; }
  Mint operator-(const Mint &a) const { return Mint(*this) -= a; }
  Mint operator*(const Mint &a) const { return Mint(*this) *= a; }
  Mint operator/(const Mint &a) const { return Mint(*this) /= a; }
  bool operator<(const Mint &a) const { return x < a.x; }
  bool operator<=(const Mint &a) const { return x <= a.x; }
  bool operator>(const Mint &a) const { return x > a.x; }
  bool operator>=(const Mint &a) const { return x >= a.x; }
  bool operator==(const Mint &a) const { return x == a.x; }
  bool operator!=(const Mint &a) const { return !(*this == a); }
  const Mint power(ll N)
  {
    if (N == 0)
    {
      return 1;
    }
    else if (N % 2 == 1)
    {
      return *this * power(N - 1);
    }
    else
    {
      Mint half = power(N / 2);
      return half * half;
    }
  }
};
template <ll MOD>
Mint<MOD> operator+(ll lhs, const Mint<MOD> &rhs)
{
  return rhs + lhs;
}
template <ll MOD>
Mint<MOD> operator-(ll lhs, const Mint<MOD> &rhs)
{
  return -rhs + lhs;
}
template <ll MOD>
Mint<MOD> operator*(ll lhs, const Mint<MOD> &rhs)
{
  return rhs * lhs;
}
template <ll MOD>
Mint<MOD> operator/(ll lhs, const Mint<MOD> &rhs)
{
  return Mint<MOD>{lhs} / rhs;
}
template <ll MOD>
istream &operator>>(istream &stream, Mint<MOD> &a)
{
  return stream >> a.x;
}
template <ll MOD>
ostream &operator<<(ostream &stream, const Mint<MOD> &a)
{
  return stream << a.x;
}
// ----- Combination -----
template <ll MOD = MOD, ll MAX_SIZE = MAX_SIZE>
class Combination
{
public:
  vector<Mint<MOD>> inv, fact, factinv;
  Combination() : inv(MAX_SIZE), fact(MAX_SIZE), factinv(MAX_SIZE)
  {
    inv[1] = 1;
    for (auto i = 2LL; i < MAX_SIZE; i++)
    {
      inv[i] = (-inv[MOD % i]) * (MOD / i);
    }
    fact[0] = factinv[0] = 1;
    for (auto i = 1LL; i < MAX_SIZE; i++)
    {
      fact[i] = Mint<MOD>(i) * fact[i - 1];
      factinv[i] = inv[i] * factinv[i - 1];
    }
  }
  Mint<MOD> operator()(int n, int k)
  {
    if (n >= 0 && k >= 0 && n - k >= 0)
    {
      return fact[n] * factinv[k] * factinv[n - k];
    }
    return 0;
  }
  Mint<MOD> catalan(int x, int y)
  {
    return (*this)(x + y, y) - (*this)(x + y, y - 1);
  }
};
// ----- for C++14 -----
using mint = Mint<MOD>;
using combination = Combination<MOD, MAX_SIZE>;
template <typename T>
T gcd(T x, T y) { return y ? gcd(y, x % y) : x; }
template <typename T>
T lcm(T x, T y) { return x / gcd(x, y) * y; }
// ----- for C++17 -----
template <typename T>
int popcount(T x) // C++20
{
  int ans{0};
  while (x != 0)
  {
    ans += x & 1;
    x >>= 1;
  }
  return ans;
}
// ----- frequently used constexpr -----
// constexpr double epsilon{1e-10};
constexpr ll infty{1000000000000000LL};
// constexpr int dx[4] = {1, 0, -1, 0};
// constexpr int dy[4] = {0, 1, 0, -1};
// ----- Yes() and No() -----
void Yes()
{
  cout << "Yes" << endl;
  exit(0);
}
void No()
{
  cout << "No" << endl;
  exit(0);
}
// ----- main() -----

using Query = tuple<ll, ll>;

int main()
{
  ll N, M, L;
  cin >> N >> M >> L;
  vector<vector<ll>> D(N, vector<ll>(N, infty));
  for (auto i = 0; i < M; ++i)
  {
    ll A, B, C;
    cin >> A >> B >> C;
    --A;
    --B;
    D[A][B] = C;
    D[B][A] = C;
  }
  ll Q;
  cin >> Q;
  vector<Query> W(Q);
  for (auto i = 0; i < Q; ++i)
  {
    int s, t;
    cin >> s >> t;
    --s;
    --t;
    W[i] = Query(s, t);
  }
  for (auto k = 0; k < N; ++k)
  {
    for (auto i = 0; i < N; ++i)
    {
      if (i == k)
      {
        continue;
      }
      for (auto j = 0; j < N; ++j)
      {
        if (i == j || j == k)
        {
          continue;
        }
        ch_min(D[i][j], D[i][k] + D[k][j]);
      }
    }
  }
#if DEBUG == 1
  for (auto i = 0; i < N; ++i)
  {
    for (auto j = 0; j < N; ++j)
    {
      cerr << "D[" << i << "][" << j << "] = " << D[i][j] << endl;
    }
  }
#endif
  vector<vector<ll>> E(N, vector<ll>(N, infty));
  for (auto i = 0; i < N; ++i)
  {
    for (auto j = 0; j < N; ++j)
    {
      if (D[i][j] <= L)
      {
        E[i][j] = 1;
      }
    }
  }
#if DEBUG == 1
  for (auto i = 0; i < N; ++i)
  {
    for (auto j = 0; j < N; ++j)
    {
      cerr << "E[" << i << "][" << j << "] = " << E[i][j] << endl;
    }
  }
#endif
  for (auto k = 0; k < N; ++k)
  {
    for (auto i = 0; i < N; ++i)
    {
      if (i == k)
      {
        continue;
      }
      for (auto j = 0; j < N; ++j)
      {
        if (i == j || j == k)
        {
          continue;
        }
        ch_min(E[i][j], E[i][k] + E[k][j]);
      }
    }
  }
#if DEBUG == 1
  for (auto i = 0; i < N; ++i)
  {
    for (auto j = 0; j < N; ++j)
    {
      cerr << "E[" << i << "][" << j << "] = " << E[i][j] << endl;
    }
  }
#endif
  for (auto i = 0; i < Q; ++i)
  {
    ll s, t;
    tie(s, t) = W[i];
    cout << (E[s][t] < infty ? E[s][t] : -1) << endl;
  }
}
<|endoftext|>


<commit_before>#define DEBUG 1
/**
 * File    : E.cpp
 * Author  : Kazune Takahashi
 * Created : 6/18/2020, 7:52:51 PM
 * Powered by Visual Studio Code
 */
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <chrono>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <vector>
// ----- boost -----
#include <boost/integer/common_factor_rt.hpp>
#include <boost/multiprecision/cpp_int.hpp>
#include <boost/rational.hpp>
// ----- using directives and manipulations -----
using namespace std;
using boost::rational;
using boost::integer::gcd; // for C++14 or for cpp_int
using boost::integer::lcm; // for C++14 or for cpp_int
using boost::multiprecision::cpp_int;
using ll = long long;
using ld = long double;
template <typename T>
using max_heap = priority_queue<T>;
template <typename T>
using min_heap = priority_queue<T, vector<T>, greater<T>>;
// ----- constexpr for Mint and Combination -----
constexpr ll MOD{1'000'000'007LL};
// constexpr ll MOD{998'244'353LL}; // be careful
constexpr ll MAX_SIZE{3'000'010LL};
// constexpr ll MAX_SIZE{30'000'010LL}; // if 10^7 is needed
// ----- ch_max and ch_min -----
template <typename T>
bool ch_max(T &left, T right)
{
  if (left < right)
  {
    left = right;
    return true;
  }
  return false;
}
template <typename T>
bool ch_min(T &left, T right)
{
  if (left > right)
  {
    left = right;
    return true;
  }
  return false;
}
// ----- Mint -----
template <ll MOD = MOD>
class Mint
{
public:
  ll x;
  Mint() : x{0LL} {}
  Mint(ll x) : x{(x % MOD + MOD) % MOD} {}
  Mint operator-() const { return x ? MOD - x : 0; }
  Mint &operator+=(Mint const &a)
  {
    if ((x += a.x) >= MOD)
    {
      x -= MOD;
    }
    return *this;
  }
  Mint &operator-=(Mint const &a) { return *this += -a; }
  Mint &operator++() { return *this += 1; }
  Mint operator++(int)
  {
    Mint tmp{*this};
    ++*this;
    return tmp;
  }
  Mint &operator--() { return *this -= 1; }
  Mint operator--(int)
  {
    Mint tmp{*this};
    --*this;
    return tmp;
  }
  Mint &operator*=(Mint const &a)
  {
    (x *= a.x) %= MOD;
    return *this;
  }
  Mint &operator/=(Mint const &a)
  {
    Mint b{a};
    return *this *= b.power(MOD - 2);
  }
  Mint operator+(Mint const &a) const { return Mint(*this) += a; }
  Mint operator-(Mint const &a) const { return Mint(*this) -= a; }
  Mint operator*(Mint const &a) const { return Mint(*this) *= a; }
  Mint operator/(Mint const &a) const { return Mint(*this) /= a; }
  bool operator<(Mint const &a) const { return x < a.x; }
  bool operator<=(Mint const &a) const { return x <= a.x; }
  bool operator>(Mint const &a) const { return x > a.x; }
  bool operator>=(Mint const &a) const { return x >= a.x; }
  bool operator==(Mint const &a) const { return x == a.x; }
  bool operator!=(Mint const &a) const { return !(*this == a); }
  Mint power(ll N) const
  {
    if (N == 0)
    {
      return 1;
    }
    else if (N % 2 == 1)
    {
      return *this * power(N - 1);
    }
    else
    {
      Mint half = power(N / 2);
      return half * half;
    }
  }
};
template <ll MOD>
Mint<MOD> operator+(ll lhs, Mint<MOD> const &rhs) { return rhs + lhs; }
template <ll MOD>
Mint<MOD> operator-(ll lhs, Mint<MOD> const &rhs) { return -rhs + lhs; }
template <ll MOD>
Mint<MOD> operator*(ll lhs, Mint<MOD> const &rhs) { return rhs * lhs; }
template <ll MOD>
Mint<MOD> operator/(ll lhs, Mint<MOD> const &rhs) { return Mint<MOD>{lhs} / rhs; }
template <ll MOD>
istream &operator>>(istream &stream, Mint<MOD> &a) { return stream >> a.x; }
template <ll MOD>
ostream &operator<<(ostream &stream, Mint<MOD> const &a) { return stream << a.x; }
// ----- Combination -----
template <ll MOD = MOD, ll MAX_SIZE = MAX_SIZE>
class Combination
{
public:
  vector<Mint<MOD>> inv, fact, factinv;
  Combination() : inv(MAX_SIZE), fact(MAX_SIZE), factinv(MAX_SIZE)
  {
    inv[1] = 1;
    for (auto i{2LL}; i < MAX_SIZE; i++)
    {
      inv[i] = (-inv[MOD % i]) * (MOD / i);
    }
    fact[0] = factinv[0] = 1;
    for (auto i{1LL}; i < MAX_SIZE; i++)
    {
      fact[i] = Mint<MOD>(i) * fact[i - 1];
      factinv[i] = inv[i] * factinv[i - 1];
    }
  }
  Mint<MOD> operator()(int n, int k)
  {
    if (n >= 0 && k >= 0 && n - k >= 0)
    {
      return fact[n] * factinv[k] * factinv[n - k];
    }
    return 0;
  }
  Mint<MOD> catalan(int x, int y)
  {
    return (*this)(x + y, y) - (*this)(x + y, y - 1);
  }
};
// ----- for C++14 -----
using mint = Mint<MOD>;
using combination = Combination<MOD, MAX_SIZE>;
// ----- for C++17 -----
template <typename T, typename enable_if<is_integral<T>::value>::type * = nullptr>
size_t popcount(T x) { return bitset<64>(x).count(); }
size_t popcount(string const &S) { return bitset<200010>{S}.count(); }
// ----- Infty -----
template <typename T>
constexpr T Infty() { return numeric_limits<T>::max(); }
template <typename T>
constexpr T mInfty() { return numeric_limits<T>::min(); }
// ----- frequently used constexpr -----
// constexpr double epsilon{1e-10};
// constexpr ll infty{1'000'000'000'000'010LL}; // or
// constexpr int infty{1'000'000'010};
// constexpr int dx[4] = {1, 0, -1, 0};
// constexpr int dy[4] = {0, 1, 0, -1};
// ----- Yes() and No() -----
void Yes()
{
  cout << "Yes" << endl;
  exit(0);
}
void No()
{
  cout << "No" << endl;
  exit(0);
}

// ----- Solve -----

class Solve
{

public:
  Solve()
  {
  }

  void flush()
  {
  }

private:
};

// ----- main() -----

/*
int main()
{
  Solve solve;
  solve.flush();
}
*/

constexpr int C{26};

int main()
{
  int N, Q;
  string S;
  cin >> N >> S >> Q;
  vector<set<int>> I(C);
  for (auto i{0}; i < N; ++i)
  {
    I[S[i] - 'a'].insert(i);
  }
  for (auto q{0}; q < N; ++q)
  {
    int type;
    cin >> type;
    if (type == 1)
    {
      int ind;
      char c;
      cin >> ind >> c;
      --ind;
      I[S[ind] - 'a'].erase(ind);
      S[ind] = c;
      I[S[ind] - 'a'].insert(ind);
    }
    else
    {
      int l, r;
      cin >> l >> r;
      --l;
      --r;
      int ans{0};
      for (auto i{0}; i < C; ++i)
      {
        auto it{I[i].lower_bound(l)};
        if (it != I[i].end() && *it <= r)
        {
          ++ans;
        }
      }
      cout << ans << endl;
    }
  }
}
<commit_msg>submit E.cpp to 'E - Simple String Queries' (abc157) [C++ (GCC 9.2.1)]<commit_after>#define DEBUG 1
/**
 * File    : E.cpp
 * Author  : Kazune Takahashi
 * Created : 6/18/2020, 7:52:51 PM
 * Powered by Visual Studio Code
 */
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <chrono>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <vector>
// ----- boost -----
#include <boost/integer/common_factor_rt.hpp>
#include <boost/multiprecision/cpp_int.hpp>
#include <boost/rational.hpp>
// ----- using directives and manipulations -----
using namespace std;
using boost::rational;
using boost::integer::gcd; // for C++14 or for cpp_int
using boost::integer::lcm; // for C++14 or for cpp_int
using boost::multiprecision::cpp_int;
using ll = long long;
using ld = long double;
template <typename T>
using max_heap = priority_queue<T>;
template <typename T>
using min_heap = priority_queue<T, vector<T>, greater<T>>;
// ----- constexpr for Mint and Combination -----
constexpr ll MOD{1'000'000'007LL};
// constexpr ll MOD{998'244'353LL}; // be careful
constexpr ll MAX_SIZE{3'000'010LL};
// constexpr ll MAX_SIZE{30'000'010LL}; // if 10^7 is needed
// ----- ch_max and ch_min -----
template <typename T>
bool ch_max(T &left, T right)
{
  if (left < right)
  {
    left = right;
    return true;
  }
  return false;
}
template <typename T>
bool ch_min(T &left, T right)
{
  if (left > right)
  {
    left = right;
    return true;
  }
  return false;
}
// ----- Mint -----
template <ll MOD = MOD>
class Mint
{
public:
  ll x;
  Mint() : x{0LL} {}
  Mint(ll x) : x{(x % MOD + MOD) % MOD} {}
  Mint operator-() const { return x ? MOD - x : 0; }
  Mint &operator+=(Mint const &a)
  {
    if ((x += a.x) >= MOD)
    {
      x -= MOD;
    }
    return *this;
  }
  Mint &operator-=(Mint const &a) { return *this += -a; }
  Mint &operator++() { return *this += 1; }
  Mint operator++(int)
  {
    Mint tmp{*this};
    ++*this;
    return tmp;
  }
  Mint &operator--() { return *this -= 1; }
  Mint operator--(int)
  {
    Mint tmp{*this};
    --*this;
    return tmp;
  }
  Mint &operator*=(Mint const &a)
  {
    (x *= a.x) %= MOD;
    return *this;
  }
  Mint &operator/=(Mint const &a)
  {
    Mint b{a};
    return *this *= b.power(MOD - 2);
  }
  Mint operator+(Mint const &a) const { return Mint(*this) += a; }
  Mint operator-(Mint const &a) const { return Mint(*this) -= a; }
  Mint operator*(Mint const &a) const { return Mint(*this) *= a; }
  Mint operator/(Mint const &a) const { return Mint(*this) /= a; }
  bool operator<(Mint const &a) const { return x < a.x; }
  bool operator<=(Mint const &a) const { return x <= a.x; }
  bool operator>(Mint const &a) const { return x > a.x; }
  bool operator>=(Mint const &a) const { return x >= a.x; }
  bool operator==(Mint const &a) const { return x == a.x; }
  bool operator!=(Mint const &a) const { return !(*this == a); }
  Mint power(ll N) const
  {
    if (N == 0)
    {
      return 1;
    }
    else if (N % 2 == 1)
    {
      return *this * power(N - 1);
    }
    else
    {
      Mint half = power(N / 2);
      return half * half;
    }
  }
};
template <ll MOD>
Mint<MOD> operator+(ll lhs, Mint<MOD> const &rhs) { return rhs + lhs; }
template <ll MOD>
Mint<MOD> operator-(ll lhs, Mint<MOD> const &rhs) { return -rhs + lhs; }
template <ll MOD>
Mint<MOD> operator*(ll lhs, Mint<MOD> const &rhs) { return rhs * lhs; }
template <ll MOD>
Mint<MOD> operator/(ll lhs, Mint<MOD> const &rhs) { return Mint<MOD>{lhs} / rhs; }
template <ll MOD>
istream &operator>>(istream &stream, Mint<MOD> &a) { return stream >> a.x; }
template <ll MOD>
ostream &operator<<(ostream &stream, Mint<MOD> const &a) { return stream << a.x; }
// ----- Combination -----
template <ll MOD = MOD, ll MAX_SIZE = MAX_SIZE>
class Combination
{
public:
  vector<Mint<MOD>> inv, fact, factinv;
  Combination() : inv(MAX_SIZE), fact(MAX_SIZE), factinv(MAX_SIZE)
  {
    inv[1] = 1;
    for (auto i{2LL}; i < MAX_SIZE; i++)
    {
      inv[i] = (-inv[MOD % i]) * (MOD / i);
    }
    fact[0] = factinv[0] = 1;
    for (auto i{1LL}; i < MAX_SIZE; i++)
    {
      fact[i] = Mint<MOD>(i) * fact[i - 1];
      factinv[i] = inv[i] * factinv[i - 1];
    }
  }
  Mint<MOD> operator()(int n, int k)
  {
    if (n >= 0 && k >= 0 && n - k >= 0)
    {
      return fact[n] * factinv[k] * factinv[n - k];
    }
    return 0;
  }
  Mint<MOD> catalan(int x, int y)
  {
    return (*this)(x + y, y) - (*this)(x + y, y - 1);
  }
};
// ----- for C++14 -----
using mint = Mint<MOD>;
using combination = Combination<MOD, MAX_SIZE>;
// ----- for C++17 -----
template <typename T, typename enable_if<is_integral<T>::value>::type * = nullptr>
size_t popcount(T x) { return bitset<64>(x).count(); }
size_t popcount(string const &S) { return bitset<200010>{S}.count(); }
// ----- Infty -----
template <typename T>
constexpr T Infty() { return numeric_limits<T>::max(); }
template <typename T>
constexpr T mInfty() { return numeric_limits<T>::min(); }
// ----- frequently used constexpr -----
// constexpr double epsilon{1e-10};
// constexpr ll infty{1'000'000'000'000'010LL}; // or
// constexpr int infty{1'000'000'010};
// constexpr int dx[4] = {1, 0, -1, 0};
// constexpr int dy[4] = {0, 1, 0, -1};
// ----- Yes() and No() -----
void Yes()
{
  cout << "Yes" << endl;
  exit(0);
}
void No()
{
  cout << "No" << endl;
  exit(0);
}

// ----- Solve -----

class Solve
{

public:
  Solve()
  {
  }

  void flush()
  {
  }

private:
};

// ----- main() -----

/*
int main()
{
  Solve solve;
  solve.flush();
}
*/

constexpr int C{26};

int main()
{
  int N, Q;
  string S;
  cin >> N >> S >> Q;
  vector<set<int>> I(C);
  for (auto i{0}; i < N; ++i)
  {
    I[S[i] - 'a'].insert(i);
  }
  for (auto q{0}; q < Q; ++q)
  {
    int type;
    cin >> type;
    if (type == 1)
    {
      int ind;
      char c;
      cin >> ind >> c;
      --ind;
      I[S[ind] - 'a'].erase(ind);
      S[ind] = c;
      I[S[ind] - 'a'].insert(ind);
    }
    else
    {
      int l, r;
      cin >> l >> r;
      --l;
      --r;
      int ans{0};
      for (auto i{0}; i < C; ++i)
      {
        auto it{I[i].lower_bound(l)};
        if (it != I[i].end() && *it <= r)
        {
          ++ans;
        }
      }
      cout << ans << endl;
    }
  }
}
<|endoftext|>


<commit_before>#define DEBUG 1
/**
 * File    : B.cpp
 * Author  : Kazune Takahashi
 * Created : 3/21/2020, 10:21:50 PM
 * Powered by Visual Studio Code
 */
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <chrono>
#include <cmath>
#include <complex>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <vector>
// ----- boost -----
#include <boost/rational.hpp>
#include <boost/multiprecision/cpp_int.hpp>
// ----- using directives and manipulations -----
using namespace std;
using boost::rational;
using boost::multiprecision::cpp_int;
using ll = long long;
template <typename T>
using max_heap = priority_queue<T>;
template <typename T>
using min_heap = priority_queue<T, vector<T>, greater<T>>;
// ----- constexpr for Mint and Combination -----
constexpr ll MOD{2LL};
// constexpr ll MOD{998244353LL}; // be careful
constexpr ll MAX_SIZE{3000010LL};
// constexpr ll MAX_SIZE{30000010LL}; // if 10^7 is needed
// ----- ch_max and ch_min -----
template <typename T>
void ch_max(T &left, T right)
{
  if (left < right)
  {
    left = right;
  }
}
template <typename T>
void ch_min(T &left, T right)
{
  if (left > right)
  {
    left = right;
  }
}
// ----- Mint -----
template <ll MOD = MOD>
class Mint
{
public:
  ll x;
  Mint() : x{0LL} {}
  Mint(ll x) : x{(x % MOD + MOD) % MOD} {}
  Mint operator-() const { return x ? MOD - x : 0; }
  Mint &operator+=(const Mint &a)
  {
    if ((x += a.x) >= MOD)
    {
      x -= MOD;
    }
    return *this;
  }
  Mint &operator-=(const Mint &a) { return *this += -a; }
  Mint &operator++() { return *this += 1; }
  Mint &operator++(int)
  {
    Mint tmp{*this};
    ++*this;
    return tmp;
  }
  Mint &operator--() { return *this -= 1; }
  Mint &operator--(int)
  {
    Mint tmp{*this};
    --*this;
    return tmp;
  }
  Mint &operator*=(const Mint &a)
  {
    (x *= a.x) %= MOD;
    return *this;
  }
  Mint &operator/=(const Mint &a)
  {
    Mint b{a};
    return *this *= b.power(MOD - 2);
  }
  Mint operator+(const Mint &a) const { return Mint(*this) += a; }
  Mint operator-(const Mint &a) const { return Mint(*this) -= a; }
  Mint operator*(const Mint &a) const { return Mint(*this) *= a; }
  Mint operator/(const Mint &a) const { return Mint(*this) /= a; }
  bool operator<(const Mint &a) const { return x < a.x; }
  bool operator<=(const Mint &a) const { return x <= a.x; }
  bool operator>(const Mint &a) const { return x > a.x; }
  bool operator>=(const Mint &a) const { return x >= a.x; }
  bool operator==(const Mint &a) const { return x == a.x; }
  bool operator!=(const Mint &a) const { return !(*this == a); }
  const Mint power(ll N)
  {
    if (N == 0)
    {
      return 1;
    }
    else if (N % 2 == 1)
    {
      return *this * power(N - 1);
    }
    else
    {
      Mint half = power(N / 2);
      return half * half;
    }
  }
};
template <ll MOD>
Mint<MOD> operator+(ll lhs, const Mint<MOD> &rhs)
{
  return rhs + lhs;
}
template <ll MOD>
Mint<MOD> operator-(ll lhs, const Mint<MOD> &rhs)
{
  return -rhs + lhs;
}
template <ll MOD>
Mint<MOD> operator*(ll lhs, const Mint<MOD> &rhs)
{
  return rhs * lhs;
}
template <ll MOD>
Mint<MOD> operator/(ll lhs, const Mint<MOD> &rhs)
{
  return Mint<MOD>{lhs} / rhs;
}
template <ll MOD>
istream &operator>>(istream &stream, Mint<MOD> &a)
{
  return stream >> a.x;
}
template <ll MOD>
ostream &operator<<(ostream &stream, const Mint<MOD> &a)
{
  return stream << a.x;
}
// ----- Combination -----
template <ll MOD = MOD, ll MAX_SIZE = MAX_SIZE>
class Combination
{
public:
  vector<Mint<MOD>> inv, fact, factinv;
  Combination() : inv(MAX_SIZE), fact(MAX_SIZE), factinv(MAX_SIZE)
  {
    inv[1] = 1;
    for (auto i = 2LL; i < MAX_SIZE; i++)
    {
      inv[i] = (-inv[MOD % i]) * (MOD / i);
    }
    fact[0] = factinv[0] = 1;
    for (auto i = 1LL; i < MAX_SIZE; i++)
    {
      fact[i] = Mint<MOD>(i) * fact[i - 1];
      factinv[i] = inv[i] * factinv[i - 1];
    }
  }
  Mint<MOD> operator()(int n, int k)
  {
    if (n >= 0 && k >= 0 && n - k >= 0)
    {
      return fact[n] * factinv[k] * factinv[n - k];
    }
    return 0;
  }
  Mint<MOD> catalan(int x, int y)
  {
    return (*this)(x + y, y) - (*this)(x + y, y - 1);
  }
};
// ----- for C++14 -----
using mint = Mint<MOD>;
using combination = Combination<MOD, MAX_SIZE>;
template <typename T>
T gcd(T x, T y) { return y ? gcd(y, x % y) : x; }
template <typename T>
T lcm(T x, T y) { return x / gcd(x, y) * y; }
// ----- for C++17 -----
template <typename T>
int popcount(T x) // C++20
{
  int ans{0};
  while (x != 0)
  {
    ans += x & 1;
    x >>= 1;
  }
  return ans;
}
// ----- frequently used constexpr -----
// constexpr double epsilon{1e-10};
// constexpr ll infty{1000000000000000LL}; // or
// constexpr int infty{1'000'000'010};
// constexpr int dx[4] = {1, 0, -1, 0};
// constexpr int dy[4] = {0, 1, 0, -1};
// ----- Yes() and No() -----
void Yes()
{
  cout << "Yes" << endl;
  exit(0);
}
void No()
{
  cout << "No" << endl;
  exit(0);
}
// ----- main() -----

class Solve
{
  int N;
  vector<int> V;
  bool zero_two;
  mint ans;

public:
  Solve(int N, vector<int> V) : N{N}, V{V}
  {
    zero_two_init();
    two_zero_conv();
    calc_ans();
    flush();
  }

private:
  void flush()
  {
    if (zero_two && ans == 1)
    {
      cout << 2 << endl;
    }
    else
    {
      cout << ans << endl;
    }
  }

  void two_zero_conv()
  {
    for (auto i = 0; i < N; ++i)
    {
      if (V[i] == 2)
      {
        V[i] = 0;
      }
    }
#if DEBUG == 1
    for (auto x : V)
    {
      cerr << x;
    }
    cerr << endl;
#endif
  }

  void calc_ans()
  {
    vector<mint> C(N);
    C[0] = 1;
    for (auto i = 1LL; i < (ll)N; ++i)
    {
      C[i] *= (N - i);
      C[i] /= i;
    }
    ans = 0;
    for (auto i = 0; i < N; ++i)
    {
      ans += C[i] * V[i];
#if DEBUG == 1
      cerr << "C[" << i << "] = " << C[i] << endl;
#endif
    }
  }

  void zero_two_init()
  {
    zero_two = true;
    for (auto i = 0; i < N; ++i)
    {
      if (V[i] == 1)
      {
        zero_two = false;
        break;
      }
    }
    if (zero_two)
    {
      for (auto i = 0; i < N; ++i)
      {
        if (V[i] == 2)
        {
          V[i] = 1;
        }
      }
    }
  }
};

int main()
{
  int N;
  cin >> N;
  vector<int> A(N);
  string S;
  cin >> S;
  for (auto i = 0; i < N; ++i)
  {
    A[i] = S[i] - '0';
    A[i]--;
  }
  Solve solve(N, A);
}
<commit_msg>tried B.cpp to 'B'<commit_after>#define DEBUG 1
/**
 * File    : B.cpp
 * Author  : Kazune Takahashi
 * Created : 3/21/2020, 10:21:50 PM
 * Powered by Visual Studio Code
 */
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <chrono>
#include <cmath>
#include <complex>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <vector>
// ----- boost -----
#include <boost/rational.hpp>
#include <boost/multiprecision/cpp_int.hpp>
// ----- using directives and manipulations -----
using namespace std;
using boost::rational;
using boost::multiprecision::cpp_int;
using ll = long long;
template <typename T>
using max_heap = priority_queue<T>;
template <typename T>
using min_heap = priority_queue<T, vector<T>, greater<T>>;
// ----- constexpr for Mint and Combination -----
constexpr ll MOD{2LL};
// constexpr ll MOD{998244353LL}; // be careful
constexpr ll MAX_SIZE{3000010LL};
// constexpr ll MAX_SIZE{30000010LL}; // if 10^7 is needed
// ----- ch_max and ch_min -----
template <typename T>
void ch_max(T &left, T right)
{
  if (left < right)
  {
    left = right;
  }
}
template <typename T>
void ch_min(T &left, T right)
{
  if (left > right)
  {
    left = right;
  }
}
// ----- Mint -----
template <ll MOD = MOD>
class Mint
{
public:
  ll x;
  Mint() : x{0LL} {}
  Mint(ll x) : x{(x % MOD + MOD) % MOD} {}
  Mint operator-() const { return x ? MOD - x : 0; }
  Mint &operator+=(const Mint &a)
  {
    if ((x += a.x) >= MOD)
    {
      x -= MOD;
    }
    return *this;
  }
  Mint &operator-=(const Mint &a) { return *this += -a; }
  Mint &operator++() { return *this += 1; }
  Mint &operator++(int)
  {
    Mint tmp{*this};
    ++*this;
    return tmp;
  }
  Mint &operator--() { return *this -= 1; }
  Mint &operator--(int)
  {
    Mint tmp{*this};
    --*this;
    return tmp;
  }
  Mint &operator*=(const Mint &a)
  {
    (x *= a.x) %= MOD;
    return *this;
  }
  Mint &operator/=(const Mint &a)
  {
    Mint b{a};
    return *this *= b.power(MOD - 2);
  }
  Mint operator+(const Mint &a) const { return Mint(*this) += a; }
  Mint operator-(const Mint &a) const { return Mint(*this) -= a; }
  Mint operator*(const Mint &a) const { return Mint(*this) *= a; }
  Mint operator/(const Mint &a) const { return Mint(*this) /= a; }
  bool operator<(const Mint &a) const { return x < a.x; }
  bool operator<=(const Mint &a) const { return x <= a.x; }
  bool operator>(const Mint &a) const { return x > a.x; }
  bool operator>=(const Mint &a) const { return x >= a.x; }
  bool operator==(const Mint &a) const { return x == a.x; }
  bool operator!=(const Mint &a) const { return !(*this == a); }
  const Mint power(ll N)
  {
    if (N == 0)
    {
      return 1;
    }
    else if (N % 2 == 1)
    {
      return *this * power(N - 1);
    }
    else
    {
      Mint half = power(N / 2);
      return half * half;
    }
  }
};
template <ll MOD>
Mint<MOD> operator+(ll lhs, const Mint<MOD> &rhs)
{
  return rhs + lhs;
}
template <ll MOD>
Mint<MOD> operator-(ll lhs, const Mint<MOD> &rhs)
{
  return -rhs + lhs;
}
template <ll MOD>
Mint<MOD> operator*(ll lhs, const Mint<MOD> &rhs)
{
  return rhs * lhs;
}
template <ll MOD>
Mint<MOD> operator/(ll lhs, const Mint<MOD> &rhs)
{
  return Mint<MOD>{lhs} / rhs;
}
template <ll MOD>
istream &operator>>(istream &stream, Mint<MOD> &a)
{
  return stream >> a.x;
}
template <ll MOD>
ostream &operator<<(ostream &stream, const Mint<MOD> &a)
{
  return stream << a.x;
}
// ----- Combination -----
template <ll MOD = MOD, ll MAX_SIZE = MAX_SIZE>
class Combination
{
public:
  vector<Mint<MOD>> inv, fact, factinv;
  Combination() : inv(MAX_SIZE), fact(MAX_SIZE), factinv(MAX_SIZE)
  {
    inv[1] = 1;
    for (auto i = 2LL; i < MAX_SIZE; i++)
    {
      inv[i] = (-inv[MOD % i]) * (MOD / i);
    }
    fact[0] = factinv[0] = 1;
    for (auto i = 1LL; i < MAX_SIZE; i++)
    {
      fact[i] = Mint<MOD>(i) * fact[i - 1];
      factinv[i] = inv[i] * factinv[i - 1];
    }
  }
  Mint<MOD> operator()(int n, int k)
  {
    if (n >= 0 && k >= 0 && n - k >= 0)
    {
      return fact[n] * factinv[k] * factinv[n - k];
    }
    return 0;
  }
  Mint<MOD> catalan(int x, int y)
  {
    return (*this)(x + y, y) - (*this)(x + y, y - 1);
  }
};
// ----- for C++14 -----
using mint = Mint<MOD>;
using combination = Combination<MOD, MAX_SIZE>;
template <typename T>
T gcd(T x, T y) { return y ? gcd(y, x % y) : x; }
template <typename T>
T lcm(T x, T y) { return x / gcd(x, y) * y; }
// ----- for C++17 -----
template <typename T>
int popcount(T x) // C++20
{
  int ans{0};
  while (x != 0)
  {
    ans += x & 1;
    x >>= 1;
  }
  return ans;
}
// ----- frequently used constexpr -----
// constexpr double epsilon{1e-10};
// constexpr ll infty{1000000000000000LL}; // or
// constexpr int infty{1'000'000'010};
// constexpr int dx[4] = {1, 0, -1, 0};
// constexpr int dy[4] = {0, 1, 0, -1};
// ----- Yes() and No() -----
void Yes()
{
  cout << "Yes" << endl;
  exit(0);
}
void No()
{
  cout << "No" << endl;
  exit(0);
}
// ----- main() -----

class Solve
{
  int N;
  vector<int> V;
  bool zero_two;
  mint ans;

public:
  Solve(int N, vector<int> V) : N{N}, V{V}
  {
    zero_two_init();
    two_zero_conv();
    calc_ans();
    flush();
  }

private:
  void flush()
  {
    if (zero_two && ans == 1)
    {
      cout << 2 << endl;
    }
    else
    {
      cout << ans << endl;
    }
  }

  void two_zero_conv()
  {
    for (auto i = 0; i < N; ++i)
    {
      if (V[i] == 2)
      {
        V[i] = 0;
      }
    }
#if DEBUG == 1
    for (auto x : V)
    {
      cerr << x;
    }
    cerr << endl;
#endif
  }

  void calc_ans()
  {
    combination C;
    ans = 0;
    for (auto i = 0; i < N; ++i)
    {
      ans += C((N - 1) % MOD, i % MOD) * V[i];
    }
  }

  void zero_two_init()
  {
    zero_two = true;
    for (auto i = 0; i < N; ++i)
    {
      if (V[i] == 1)
      {
        zero_two = false;
        break;
      }
    }
    if (zero_two)
    {
      for (auto i = 0; i < N; ++i)
      {
        if (V[i] == 2)
        {
          V[i] = 1;
        }
      }
    }
  }
};

int main()
{
  int N;
  cin >> N;
  vector<int> A(N);
  string S;
  cin >> S;
  for (auto i = 0; i < N; ++i)
  {
    A[i] = S[i] - '0';
    A[i]--;
  }
  Solve solve(N, A);
}
<|endoftext|>


<commit_before>#define DEBUG 1
/**
 * File    : F.cpp
 * Author  : Kazune Takahashi
 * Created : 2020/6/21 1:36:25
 * Powered by Visual Studio Code
 */
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <chrono>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <vector>
// ----- boost -----
#include <boost/integer/common_factor_rt.hpp>
#include <boost/multiprecision/cpp_int.hpp>
#include <boost/rational.hpp>
// ----- using directives and manipulations -----
using namespace std;
using boost::rational;
using boost::integer::gcd; // for C++14 or for cpp_int
using boost::integer::lcm; // for C++14 or for cpp_int
using boost::multiprecision::cpp_int;
using ll = long long;
using ld = long double;
template <typename T>
using max_heap = priority_queue<T>;
template <typename T>
using min_heap = priority_queue<T, vector<T>, greater<T>>;
// ----- constexpr for Mint and Combination -----
constexpr ll MOD{1'000'000'007LL};
// constexpr ll MOD{998'244'353LL}; // be careful
constexpr ll MAX_SIZE{3'000'010LL};
// constexpr ll MAX_SIZE{30'000'010LL}; // if 10^7 is needed
// ----- ch_max and ch_min -----
template <typename T>
bool ch_max(T &left, T right)
{
  if (left < right)
  {
    left = right;
    return true;
  }
  return false;
}
template <typename T>
bool ch_min(T &left, T right)
{
  if (left > right)
  {
    left = right;
    return true;
  }
  return false;
}
// ----- Mint -----
template <ll MOD = MOD>
class Mint
{
public:
  ll x;
  Mint() : x{0LL} {}
  Mint(ll x) : x{(x % MOD + MOD) % MOD} {}
  Mint operator-() const { return x ? MOD - x : 0; }
  Mint &operator+=(Mint const &a)
  {
    if ((x += a.x) >= MOD)
    {
      x -= MOD;
    }
    return *this;
  }
  Mint &operator-=(Mint const &a) { return *this += -a; }
  Mint &operator++() { return *this += 1; }
  Mint operator++(int)
  {
    Mint tmp{*this};
    ++*this;
    return tmp;
  }
  Mint &operator--() { return *this -= 1; }
  Mint operator--(int)
  {
    Mint tmp{*this};
    --*this;
    return tmp;
  }
  Mint &operator*=(Mint const &a)
  {
    (x *= a.x) %= MOD;
    return *this;
  }
  Mint &operator/=(Mint const &a)
  {
    Mint b{a};
    return *this *= b.power(MOD - 2);
  }
  Mint operator+(Mint const &a) const { return Mint(*this) += a; }
  Mint operator-(Mint const &a) const { return Mint(*this) -= a; }
  Mint operator*(Mint const &a) const { return Mint(*this) *= a; }
  Mint operator/(Mint const &a) const { return Mint(*this) /= a; }
  bool operator<(Mint const &a) const { return x < a.x; }
  bool operator<=(Mint const &a) const { return x <= a.x; }
  bool operator>(Mint const &a) const { return x > a.x; }
  bool operator>=(Mint const &a) const { return x >= a.x; }
  bool operator==(Mint const &a) const { return x == a.x; }
  bool operator!=(Mint const &a) const { return !(*this == a); }
  Mint power(ll N) const
  {
    if (N == 0)
    {
      return 1;
    }
    else if (N % 2 == 1)
    {
      return *this * power(N - 1);
    }
    else
    {
      Mint half = power(N / 2);
      return half * half;
    }
  }
};
template <ll MOD>
Mint<MOD> operator+(ll lhs, Mint<MOD> const &rhs) { return rhs + lhs; }
template <ll MOD>
Mint<MOD> operator-(ll lhs, Mint<MOD> const &rhs) { return -rhs + lhs; }
template <ll MOD>
Mint<MOD> operator*(ll lhs, Mint<MOD> const &rhs) { return rhs * lhs; }
template <ll MOD>
Mint<MOD> operator/(ll lhs, Mint<MOD> const &rhs) { return Mint<MOD>{lhs} / rhs; }
template <ll MOD>
istream &operator>>(istream &stream, Mint<MOD> &a) { return stream >> a.x; }
template <ll MOD>
ostream &operator<<(ostream &stream, Mint<MOD> const &a) { return stream << a.x; }
// ----- Combination -----
template <ll MOD = MOD, ll MAX_SIZE = MAX_SIZE>
class Combination
{
public:
  vector<Mint<MOD>> inv, fact, factinv;
  Combination() : inv(MAX_SIZE), fact(MAX_SIZE), factinv(MAX_SIZE)
  {
    inv[1] = 1;
    for (auto i{2LL}; i < MAX_SIZE; i++)
    {
      inv[i] = (-inv[MOD % i]) * (MOD / i);
    }
    fact[0] = factinv[0] = 1;
    for (auto i{1LL}; i < MAX_SIZE; i++)
    {
      fact[i] = Mint<MOD>(i) * fact[i - 1];
      factinv[i] = inv[i] * factinv[i - 1];
    }
  }
  Mint<MOD> operator()(int n, int k)
  {
    if (n >= 0 && k >= 0 && n - k >= 0)
    {
      return fact[n] * factinv[k] * factinv[n - k];
    }
    return 0;
  }
  Mint<MOD> catalan(int x, int y)
  {
    return (*this)(x + y, y) - (*this)(x + y, y - 1);
  }
};
// ----- for C++14 -----
using mint = Mint<MOD>;
using combination = Combination<MOD, MAX_SIZE>;
// ----- for C++17 -----
template <typename T, typename enable_if<is_integral<T>::value>::type * = nullptr>
size_t popcount(T x) { return bitset<64>(x).count(); }
size_t popcount(string const &S) { return bitset<200010>{S}.count(); }
// ----- Infty -----
template <typename T>
constexpr T Infty() { return numeric_limits<T>::max(); }
template <typename T>
constexpr T mInfty() { return numeric_limits<T>::min(); }
// ----- frequently used constexpr -----
// constexpr double epsilon{1e-10};
// constexpr ll infty{1'000'000'000'000'010LL}; // or
// constexpr int infty{1'000'000'010};
// constexpr int dx[4] = {1, 0, -1, 0};
// constexpr int dy[4] = {0, 1, 0, -1};
// ----- Yes() and No() -----
void Yes()
{
  cout << "Yes" << endl;
  exit(0);
}
void No()
{
  cout << "No" << endl;
  exit(0);
}

// ----- ReadGraph -----
// Referring to ymatsux-san's source code: https://atcoder.jp/contests/abc138/submissions/7016619

struct Edge
{
  int src, dst, id, rev_id;
  // ll cost;
  Edge() {}
  Edge(int src, int dst, int id, int rev_id) : src{src}, dst{dst}, id{id}, rev_id{rev_id} {}
  // Edge(int src, int dst, ll cost) : src{src}, dst{dst}, cost{cost} {}

  void added_edge(vector<vector<Edge>> &V)
  {
    V[src].push_back(*this);
  }

  void added_rev(vector<vector<Edge>> &V)
  {
    V[dst].push_back(rev());
  }

  Edge rev()
  {
    Edge edge{*this};
    swap(edge.src, edge.dst);
    return edge;
  }
};

tuple<vector<vector<Edge>>, vector<Edge>> ReadGraphWithEdges(int N, int M, bool is_undirected = true, bool is_one_indexed = true)
{
  vector<vector<Edge>> V(N);
  vector<Edge> E(2 * M);
  int ind{0};
  for (auto i = 0; i < M; ++i)
  {
    int v, w;
    cin >> v >> w;
    if (is_one_indexed)
    {
      --v;
      --w;
    }
    Edge edge{v, w, ind, ind + 1};
    edge.added_edge(V);
    E[ind++] = edge;
    Edge edge_rev{w, v, ind, ind - 1};
    edge_rev.added_edge(V);
    E[ind++] = edge_rev;
  }
  return make_tuple(V, E);
}

vector<vector<Edge>> ReadGraph(int N, int M, bool is_undirected = true, bool is_one_indexed = true)
{
  return get<0>(ReadGraphWithEdges(N, M, is_undirected, is_one_indexed));
}

tuple<vector<vector<Edge>>, vector<Edge>> ReadTreeWithEdges(int N)
{
  return ReadGraphWithEdges(N, N - 1);
}

vector<vector<Edge>> ReadTree(int N)
{
  return ReadGraph(N, N - 1);
}

// ----- Solve -----

combination C;

class Solve
{
  int N;
  vector<vector<Edge>> V;
  vector<Edge> E;
  vector<ll> S;
  vector<mint> dp;
  vector<bool> visited_S;
  vector<bool> visited_dp;

public:
  Solve(int N) : N{N}, S(2 * N - 2, 0), dp(2 * N - 2, 0), visited_S(2 * N - 2, false), visited_dp(2 * N - 2, false)
  {
    tie(V, E) = ReadTreeWithEdges(N);
  }

  void flush()
  {
    for (auto i{0}; i < N; ++i)
    {
      cout << answer(i) << endl;
    }
  }

private:
  ll children_size(int v)
  {
    ll T{1};
    for (auto const &e : V[v])
    {
      T += calc_S(e.id);
    }
    for (auto const &e : V[v])
    {
      auto X{T};
      X -= calc_S(e.id);
      S[e.rev_id] = X;
      visited_S[e.rev_id] = true;
    }
    return T;
  }

  mint answer(int v)
  {
    auto T{children_size(v)};
    auto ans{C.fact[T - 1]};
    for (auto const &e : V[v])
    {
      ans *= calc_dp(e.id) * C.factinv[calc_S(e.id)];
    }
    for (auto const &e : V[v])
    {
      auto X{ans};
      X /= C.fact[T - 1];
      X *= C.fact[calc_S(e.rev_id) - 1];
      X /= calc_dp(e.id) * C.factinv[calc_S(e.id)];
      dp[e.rev_id] = X;
      visited_dp[e.rev_id] = true;
    }
    return ans;
  }

  ll calc_S(int id)
  {
    if (visited_S[id])
    {
      return S[id];
    }
    visited_S[id] = true;
    auto src{E[id].dst};
    auto parent{E[id].src};
    S[id] = 1;
    for (auto const &e : V[src])
    {
      if (e.dst == parent)
      {
        continue;
      }
      S[id] += calc_S(e.id);
    }
    return S[id];
  }

  mint calc_dp(int id)
  {
    if (visited_dp[id])
    {
      return dp[id];
    }
    visited_dp[id] = true;
    auto src{E[id].dst};
    auto parent{E[id].src};
    dp[id] = C.fact[calc_S(id) - 1];
    for (auto const &e : V[src])
    {
      if (e.dst == parent)
      {
        continue;
      }
      dp[id] *= calc_dp(e.id) * C.factinv[calc_S(e.id)];
    }
    return dp[id];
  }
};

// ----- main() -----

int main()
{
  int N;
  cin >> N;
  Solve solve(N);
  solve.flush();
}
<commit_msg>submit F.cpp to 'F - Distributing Integers' (abc160) [C++ (GCC 9.2.1)]<commit_after>#define DEBUG 1
/**
 * File    : F.cpp
 * Author  : Kazune Takahashi
 * Created : 2020/6/21 1:36:25
 * Powered by Visual Studio Code
 */
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <chrono>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <vector>
// ----- boost -----
#include <boost/integer/common_factor_rt.hpp>
#include <boost/multiprecision/cpp_int.hpp>
#include <boost/rational.hpp>
// ----- using directives and manipulations -----
using namespace std;
using boost::rational;
using boost::integer::gcd; // for C++14 or for cpp_int
using boost::integer::lcm; // for C++14 or for cpp_int
using boost::multiprecision::cpp_int;
using ll = long long;
using ld = long double;
template <typename T>
using max_heap = priority_queue<T>;
template <typename T>
using min_heap = priority_queue<T, vector<T>, greater<T>>;
// ----- constexpr for Mint and Combination -----
constexpr ll MOD{1'000'000'007LL};
// constexpr ll MOD{998'244'353LL}; // be careful
constexpr ll MAX_SIZE{3'000'010LL};
// constexpr ll MAX_SIZE{30'000'010LL}; // if 10^7 is needed
// ----- ch_max and ch_min -----
template <typename T>
bool ch_max(T &left, T right)
{
  if (left < right)
  {
    left = right;
    return true;
  }
  return false;
}
template <typename T>
bool ch_min(T &left, T right)
{
  if (left > right)
  {
    left = right;
    return true;
  }
  return false;
}
// ----- Mint -----
template <ll MOD = MOD>
class Mint
{
public:
  ll x;
  Mint() : x{0LL} {}
  Mint(ll x) : x{(x % MOD + MOD) % MOD} {}
  Mint operator-() const { return x ? MOD - x : 0; }
  Mint &operator+=(Mint const &a)
  {
    if ((x += a.x) >= MOD)
    {
      x -= MOD;
    }
    return *this;
  }
  Mint &operator-=(Mint const &a) { return *this += -a; }
  Mint &operator++() { return *this += 1; }
  Mint operator++(int)
  {
    Mint tmp{*this};
    ++*this;
    return tmp;
  }
  Mint &operator--() { return *this -= 1; }
  Mint operator--(int)
  {
    Mint tmp{*this};
    --*this;
    return tmp;
  }
  Mint &operator*=(Mint const &a)
  {
    (x *= a.x) %= MOD;
    return *this;
  }
  Mint &operator/=(Mint const &a)
  {
    Mint b{a};
    return *this *= b.power(MOD - 2);
  }
  Mint operator+(Mint const &a) const { return Mint(*this) += a; }
  Mint operator-(Mint const &a) const { return Mint(*this) -= a; }
  Mint operator*(Mint const &a) const { return Mint(*this) *= a; }
  Mint operator/(Mint const &a) const { return Mint(*this) /= a; }
  bool operator<(Mint const &a) const { return x < a.x; }
  bool operator<=(Mint const &a) const { return x <= a.x; }
  bool operator>(Mint const &a) const { return x > a.x; }
  bool operator>=(Mint const &a) const { return x >= a.x; }
  bool operator==(Mint const &a) const { return x == a.x; }
  bool operator!=(Mint const &a) const { return !(*this == a); }
  Mint power(ll N) const
  {
    if (N == 0)
    {
      return 1;
    }
    else if (N % 2 == 1)
    {
      return *this * power(N - 1);
    }
    else
    {
      Mint half = power(N / 2);
      return half * half;
    }
  }
};
template <ll MOD>
Mint<MOD> operator+(ll lhs, Mint<MOD> const &rhs) { return rhs + lhs; }
template <ll MOD>
Mint<MOD> operator-(ll lhs, Mint<MOD> const &rhs) { return -rhs + lhs; }
template <ll MOD>
Mint<MOD> operator*(ll lhs, Mint<MOD> const &rhs) { return rhs * lhs; }
template <ll MOD>
Mint<MOD> operator/(ll lhs, Mint<MOD> const &rhs) { return Mint<MOD>{lhs} / rhs; }
template <ll MOD>
istream &operator>>(istream &stream, Mint<MOD> &a) { return stream >> a.x; }
template <ll MOD>
ostream &operator<<(ostream &stream, Mint<MOD> const &a) { return stream << a.x; }
// ----- Combination -----
template <ll MOD = MOD, ll MAX_SIZE = MAX_SIZE>
class Combination
{
public:
  vector<Mint<MOD>> inv, fact, factinv;
  Combination() : inv(MAX_SIZE), fact(MAX_SIZE), factinv(MAX_SIZE)
  {
    inv[1] = 1;
    for (auto i{2LL}; i < MAX_SIZE; i++)
    {
      inv[i] = (-inv[MOD % i]) * (MOD / i);
    }
    fact[0] = factinv[0] = 1;
    for (auto i{1LL}; i < MAX_SIZE; i++)
    {
      fact[i] = Mint<MOD>(i) * fact[i - 1];
      factinv[i] = inv[i] * factinv[i - 1];
    }
  }
  Mint<MOD> operator()(int n, int k)
  {
    if (n >= 0 && k >= 0 && n - k >= 0)
    {
      return fact[n] * factinv[k] * factinv[n - k];
    }
    return 0;
  }
  Mint<MOD> catalan(int x, int y)
  {
    return (*this)(x + y, y) - (*this)(x + y, y - 1);
  }
};
// ----- for C++14 -----
using mint = Mint<MOD>;
using combination = Combination<MOD, MAX_SIZE>;
// ----- for C++17 -----
template <typename T, typename enable_if<is_integral<T>::value>::type * = nullptr>
size_t popcount(T x) { return bitset<64>(x).count(); }
size_t popcount(string const &S) { return bitset<200010>{S}.count(); }
// ----- Infty -----
template <typename T>
constexpr T Infty() { return numeric_limits<T>::max(); }
template <typename T>
constexpr T mInfty() { return numeric_limits<T>::min(); }
// ----- frequently used constexpr -----
// constexpr double epsilon{1e-10};
// constexpr ll infty{1'000'000'000'000'010LL}; // or
// constexpr int infty{1'000'000'010};
// constexpr int dx[4] = {1, 0, -1, 0};
// constexpr int dy[4] = {0, 1, 0, -1};
// ----- Yes() and No() -----
void Yes()
{
  cout << "Yes" << endl;
  exit(0);
}
void No()
{
  cout << "No" << endl;
  exit(0);
}

// ----- ReadGraph -----
// Referring to ymatsux-san's source code: https://atcoder.jp/contests/abc138/submissions/7016619

struct Edge
{
  int src, dst, id, rev_id;
  // ll cost;
  Edge() {}
  Edge(int src, int dst, int id, int rev_id) : src{src}, dst{dst}, id{id}, rev_id{rev_id} {}
  // Edge(int src, int dst, ll cost) : src{src}, dst{dst}, cost{cost} {}

  void added_edge(vector<vector<Edge>> &V)
  {
    V[src].push_back(*this);
  }

  void added_rev(vector<vector<Edge>> &V)
  {
    V[dst].push_back(rev());
  }

  Edge rev()
  {
    Edge edge{*this};
    swap(edge.src, edge.dst);
    return edge;
  }
};

tuple<vector<vector<Edge>>, vector<Edge>> ReadGraphWithEdges(int N, int M, bool is_undirected = true, bool is_one_indexed = true)
{
  vector<vector<Edge>> V(N);
  vector<Edge> E(2 * M);
  int ind{0};
  for (auto i = 0; i < M; ++i)
  {
    int v, w;
    cin >> v >> w;
    if (is_one_indexed)
    {
      --v;
      --w;
    }
    Edge edge{v, w, ind, ind + 1};
    edge.added_edge(V);
    E[ind++] = edge;
    Edge edge_rev{w, v, ind, ind - 1};
    edge_rev.added_edge(V);
    E[ind++] = edge_rev;
  }
  return make_tuple(V, E);
}

vector<vector<Edge>> ReadGraph(int N, int M, bool is_undirected = true, bool is_one_indexed = true)
{
  return get<0>(ReadGraphWithEdges(N, M, is_undirected, is_one_indexed));
}

tuple<vector<vector<Edge>>, vector<Edge>> ReadTreeWithEdges(int N)
{
  return ReadGraphWithEdges(N, N - 1);
}

vector<vector<Edge>> ReadTree(int N)
{
  return ReadGraph(N, N - 1);
}

// ----- Solve -----

combination C;

class Solve
{
  int N;
  vector<vector<Edge>> V;
  vector<Edge> E;
  vector<ll> S;
  vector<mint> dp;
  vector<bool> visited_S;
  vector<bool> visited_dp;

public:
  Solve(int N) : N{N}, S(2 * N - 2, 0), dp(2 * N - 2, 0), visited_S(2 * N - 2, false), visited_dp(2 * N - 2, false)
  {
    tie(V, E) = ReadTreeWithEdges(N);
  }

  void flush()
  {
    for (auto i{0}; i < N; ++i)
    {
      cout << answer(i) << endl;
    }
  }

private:
  ll children_size(int v)
  {
    ll T{1};
    for (auto const &e : V[v])
    {
      T += calc_S(e.id);
    }
    for (auto const &e : V[v])
    {
      if (visited_S[e.rev_id])
      {
        continue;
      }
      auto X{T};
      X -= calc_S(e.id);
      S[e.rev_id] = X;
      visited_S[e.rev_id] = true;
    }
    return T;
  }

  mint answer(int v)
  {
    auto T{children_size(v)};
    auto ans{C.fact[T - 1]};
    for (auto const &e : V[v])
    {
      ans *= calc_dp(e.id) * C.factinv[calc_S(e.id)];
    }
    for (auto const &e : V[v])
    {
      if (visited_dp[e.rev_id])
      {
        continue;
      }
      auto X{ans};
      X /= C.fact[T - 1];
      X *= C.fact[calc_S(e.rev_id) - 1];
      X /= calc_dp(e.id) * C.factinv[calc_S(e.id)];
      dp[e.rev_id] = X;
      visited_dp[e.rev_id] = true;
    }
    return ans;
  }

  ll calc_S(int id)
  {
    if (visited_S[id])
    {
      return S[id];
    }
    visited_S[id] = true;
    auto src{E[id].dst};
    auto parent{E[id].src};
    S[id] = 1;
    for (auto const &e : V[src])
    {
      if (e.dst == parent)
      {
        continue;
      }
      S[id] += calc_S(e.id);
    }
    return S[id];
  }

  mint calc_dp(int id)
  {
    if (visited_dp[id])
    {
      return dp[id];
    }
    visited_dp[id] = true;
    auto src{E[id].dst};
    auto parent{E[id].src};
    dp[id] = C.fact[calc_S(id) - 1];
    for (auto const &e : V[src])
    {
      if (e.dst == parent)
      {
        continue;
      }
      dp[id] *= calc_dp(e.id) * C.factinv[calc_S(e.id)];
    }
    return dp[id];
  }
};

// ----- main() -----

int main()
{
  int N;
  cin >> N;
  Solve solve(N);
  solve.flush();
}
<|endoftext|>


<commit_before>/*********************************************************************************
- Contact:    Michal Broz     Michal.Broz@cern.ch
- Link:       http
- Raw data test file :
- Reference run number :
- Run Type:   PHYSICS
- DA Type:    MON
- Number of events needed: >=500
- Input Files:  argument list
- Output Files: local files  AD0_Histos.root, AD0_Pedestals_On.dat (Online mapping)
                FXS file     AD0_Pedestals_Off.dat (Offline mapping)
- Trigger types used: PHYSICS_EVENT
**********************************************************************************/

/**********************************************************************************
*                                                                                *
* AD Detector Algorithm used for extracting calibration parameters             *
*                                                                                *
* This program connects to the DAQ data source passed as argument.                *
* It computes calibration parameters, populates local "./AD0_Pedestals_On.dat"   *
* file, exports it to the FES, and stores it into DAQ DB                          *
* The program exits when being asked to shut down (daqDA_checkshutdown)           *
* or on End of Run event.                                                         *
* We have 32 channels instead of 16 as expected for AD0 due to the two sets of    *
* charge integrators which are used by the FEE ...                                *
*                                                                                *
***********************************************************************************/

// DATE
#include "event.h"
#include "monitor.h"
#include "daqDA.h"

//AliRoot
#include <AliADConst.h>
#include <AliADRawStream.h>
#include <AliRawReaderDate.h>
#include <AliRawReader.h>
#include <AliDAQ.h>

// standard
#include <stdio.h>
#include <stdlib.h>

//ROOT
#include "TROOT.h"
#include "TPluginManager.h"
#include <TFile.h>
#include <TH1F.h>
#include <TMath.h>

/* Main routine --- Arguments: monitoring data source */

int main(int argc, char **argv) {

/* magic line from Cvetan */
  gROOT->GetPluginManager()->AddHandler("TVirtualStreamerInfo","*","TStreamerInfo","RIO","TStreamerInfo()");

  int status;
  if (argc!=2) {
     printf("Wrong number of arguments\n");
     return -1;
  }

  // Online values (using FEE channel numbering),
  // stored into local AD0_Pedestals_On.dat:
  Double_t adcMean[32];
  Double_t adcSigma[32];
  Double_t pedMean[32];
  Double_t pedSigma[32];
  // Offline values(same but ordered as in aliroot for offliners)
  // stored into AD0_Pedestals_Off.dat:
  Double_t adcMeanOff[32];
  Double_t adcSigmaOff[32];
  Double_t pedMeanOff[32];
  Double_t pedSigmaOff[32];

//___________________________________________________
// Get cuts from V00DA.config file

  Int_t    kClockMin;   // = 16;   LHC Clock Min for pedestal calculation
  Int_t    kClockMax;   // = 19;   LHC Clock Max for pedestal calculation
  Int_t    kLowCut;     // = 60;   low cut on signal distribution - to be tuned
  Int_t    kHighCut;    // = 50;   high cut on pedestal distribution - to be tuned
  Int_t    kClockMinRef;   // = 16;   LHC Clock Min for Flag checking
  Int_t    kClockMaxRef;   // = 20;   LHC Clock Max for Flag checking
  Float_t  kChi2Max; 		// = 1.  Maximum chi2

  status = daqDA_DB_getFile("AD0_Pedestal_DA.config","./AD0_Pedestal_DA.config");
  if (status) {
      printf("Failed to get Config file (AD0_Pedestal_DA.config) from DAQ DB, status=%d\n", status);
      printf("Take default values of parameters for pedestal calculation \n");
      kClockMin  =  16;
      kClockMax  =  19;
      kLowCut    =  60;
      kHighCut   =  50;
      kClockMinRef  =  16;
      kClockMaxRef  =  20;
      kChi2Max		=  100.;
  } else {
      /* open the config file and retrieve cuts */
      FILE *fpConfig = fopen("AD0_Pedestal_DA.config","r");
      int res = fscanf(fpConfig,"%d %d %d %d %d %d %f",&kClockMin,&kClockMax,&kLowCut,&kHighCut,&kClockMinRef,&kClockMaxRef,&kChi2Max);
      if(res!=7) {
	    printf("Failed to get values from Config file (AD0_Pedestal_DA.config): wrong file format - 7 integers are expected - \n");
	    kClockMin  =  16;
        kClockMax  =  19;
    	kLowCut    =  60;
        kHighCut   =  50;
      	kClockMinRef  =  16;
      	kClockMaxRef  =  20;
      	kChi2Max	  =  100.;
      }
      fclose(fpConfig);
  }

  printf("LHC Clock Min for pedestal calculation = %d; LHC Clock Max for pedestal calculation = %d; LowCut on signal = %d ; HighCut on pedestal = %d\n",
          kClockMin, kClockMax, kLowCut, kHighCut);

//___________________________________________________
// Book HISTOGRAMS - dynamics of p-p collisions -

  char     adcName[6];
  char     pedName[6];
  TH1F     *hADCname[32];
  TH1F     *hPEDname[32];

  char  texte[12];
  for (Int_t i=0; i<16; i++) {
  	for(Int_t j=0; j<2; j++){
       		sprintf(adcName,"hADC%d%d",i,j);
       		sprintf(texte,"ADC cell%d int%d",i,j);
       		hADCname[i + 16*j]  = new TH1F(adcName,texte,1024,-0.5, 1023.5);
       		sprintf(pedName,"hPED%d%d",i,j);
       		sprintf(texte,"PED cell%d int%d",i,j);
       		hPEDname[i + 16*j]  = new TH1F(pedName,texte,1024,-0.5, 1023.5);
       		}
       }
//___________________________________________________

  /* open result file to be exported to FES */
  FILE *fpLocal=NULL;
  fpLocal=fopen("./AD0_Pedestals_On.dat","w");
  if (fpLocal==NULL) {
      printf("Failed to open local result file\n");
      return -1;}

  /* open result file to be exported to FES */
  FILE *fp=NULL;
  fp=fopen("./AD0_Pedestals_Off.dat","w");
  if (fp==NULL) {
      printf("Failed to open result file\n");
      return -1;}

  /* define data source : this is argument 1 */
  status=monitorSetDataSource( argv[1] );
  if (status!=0) {
     printf("monitorSetDataSource() failed : %s\n",monitorDecodeError(status));
     return -1;
  }

  /* declare monitoring program */
  status=monitorDeclareMp( __FILE__ );
  if (status!=0) {
    printf("monitorDeclareMp() failed : %s\n",monitorDecodeError(status));
    return -1;
  }

  /* define wait event timeout - 1s max */
  monitorSetNowait();
  monitorSetNoWaitNetworkTimeout(1000);

  /* init counters on events */
  int neventsPhysics=0;
  int neventsTotal=0;

  /* loop on events (infinite) */
  for(;;) {
      struct eventHeaderStruct *event;
      eventTypeType eventT;

      /* check shutdown condition */
      if (daqDA_checkShutdown()) {break;}

      /* get next event (blocking call until timeout) */
      status=monitorGetEventDynamic((void **)&event);
      if (status==MON_ERR_EOF) {
          printf ("End of File detected\n");
      break; /* end of monitoring file has been reached */
      }

      if (status!=0) {
           printf("monitorGetEventDynamic() failed : %s\n",monitorDecodeError(status));
      break;
      }

      /* retry if got no event */
      if (event==NULL) continue;

      /* decode event */
      eventT=event->eventType;

      switch (event->eventType){

      case START_OF_RUN:
           break;

      case END_OF_RUN:
           printf("End Of Run detected\n");
           break;

      case PHYSICS_EVENT:
           neventsPhysics++;

	   AliRawReader *rawReader = new AliRawReaderDate((void*)event);

	   AliADRawStream* rawStream  = new AliADRawStream(rawReader);
	   if (rawStream->Next()) {
           for(Int_t i=0; i<16; i++) {
	   		Int_t nFlag = 0;
			for(Int_t j=kClockMinRef; j <= kClockMaxRef; j++) {  // Check flags on clock range used for pedestal calculation
		   		if((rawStream->GetBBFlag(i,j)) || (rawStream->GetBGFlag(i,j))) nFlag++;
			}
			if(nFlag == 0){       // Fill 16*2 pedestal histograms  - 2 integrators -
				Float_t sum[2] = {0.,0.};
				Float_t sumwi[2] = {0.,0.};
		   		for(Int_t j=kClockMin;j <= kClockMax;j++){
		       		Int_t integrator = rawStream->GetIntegratorFlag(i,j);
		       		Float_t pedestal = (float)(rawStream->GetPedestal(i,j));
		       		sum[integrator] += pedestal;
		   			sumwi[integrator] += 1.;
		   		}
		   		Float_t mean[2] =  {0.,0.};
		   		Float_t chi2[2] =  {0.,0.};

	   			for(int ii=0;ii<2;ii++) if(sumwi[ii]>1.e-6) mean[ii] = sum[ii] / sumwi[ii];

				for(Int_t j=kClockMin;j <= kClockMax;j++){
		       		Int_t integrator = rawStream->GetIntegratorFlag(i,j);
		       		Float_t pedestal = (float)(rawStream->GetPedestal(i,j));
		   			chi2[integrator] += (mean[integrator] - pedestal) * (mean[integrator] - pedestal);
	   			}
	   			if(chi2[0]<kChi2Max && chi2[1]<kChi2Max) {
					for(int ii=0;ii<2;ii++){
						if(mean[ii] >1.e-6) hPEDname[i + 16*ii]->Fill(mean[ii]);
					}
				}

			}
			if((rawStream->GetBBFlag(i,10)) || (rawStream->GetBGFlag(i,10))){ // Charge
		    	Int_t integrator = rawStream->GetIntegratorFlag(i,10);
		    	Float_t charge = (float)(rawStream->GetADC(i));   // Fill 16*2 ADCmax histograms
		    	hADCname[i + 16 * integrator]->Fill(charge);
			}
    	} // End loop over channels
	   }   // End : if rawstream
           delete rawStream;
           rawStream = 0x0;
           delete rawReader;
           rawReader = 0x0;
      } // end of switch on event type

      neventsTotal++;
      /* free resources */
      free(event);

      /* exit when last event received, no need to wait for TERM signal */
      if (eventT==END_OF_RUN) {
           printf("End Of Run event detected\n");
      break;
    }

  }  // loop over events

  printf("%d physics events processed\n",neventsPhysics);

//___________________________________________________________________________
//  Computes mean values, converts FEE channels into Offline AliRoot channels
//  and dumps the ordered values into the output text file for SHUTTLE

  for(Int_t i=0; i<32; i++) {
      hPEDname[i]->GetXaxis()->SetRange(0,kHighCut);
      pedMean[i]  = hPEDname[i]->GetMean();
      pedSigma[i] = hPEDname[i]->GetRMS();
      hADCname[i]->GetXaxis()->SetRange(kLowCut,1024);
      adcMean[i]  = hADCname[i]->GetMean();
      adcSigma[i] = hADCname[i]->GetRMS();
//      printf(" i = %d, %.3f %.3f %.3f %.3f\n",i,pedMean[i],pedSigma[i],adcMean[i],adcSigma[i]);
      fprintf(fpLocal," %.3f %.3f %.3f %.3f\n",pedMean[i],pedSigma[i],adcMean[i],adcSigma[i]);

      if (i < 16) {
          Int_t j = kOfflineChannel[i];;
          pedMeanOff[j]  = pedMean[i];
          pedSigmaOff[j] = pedSigma[i];
          adcMeanOff[j]  = adcMean[i];
          adcSigmaOff[j] = adcSigma[i];
	  }
      else{
          Int_t j = kOfflineChannel[i-16];
          pedMeanOff[j+16]  = pedMean[i];
          pedSigmaOff[j+16] = pedSigma[i];
          adcMeanOff[j+16]  = adcMean[i];
          adcSigmaOff[j+16] = adcSigma[i];
      }
  }

  for(Int_t j=0; j<32; j++) {
//      printf(" j = %d, %.3f %.3f %.3f %.3f\n",j,pedMeanOff[j],pedSigmaOff[j],
//                                                adcMeanOff[j],adcSigmaOff[j]);
      fprintf(fp," %.3f %.3f %.3f %.3f\n",pedMeanOff[j],pedSigmaOff[j],
                                          adcMeanOff[j],adcSigmaOff[j]);
  }

//________________________________________________________________________
// Write root file with histos for users further check - just in case -

  TFile *histoFile = new TFile("AD0_Pedestals.root","RECREATE");

  for (Int_t i=0; i<32; i++) {
       hADCname[i]->GetXaxis()->SetRange(0,1024);
       hADCname[i]->Write();
       hPEDname[i]->Write(); }

  histoFile->Close();
  delete histoFile;

//________________________________________________________________________

  /* close local result file and FXS result file*/
  fclose(fpLocal);
  fclose(fp);

  /* export result file to FES */
  status=daqDA_FES_storeFile("./AD0_Pedestals_Off.dat","AD0da_results");
  if (status)    {
      printf("Failed to export file : %d\n",status);
      return -1; }

  /* store result file into Online DB */
  status=daqDA_DB_storeFile("./AD0_Pedestals_On.dat","AD0da_results");
  if (status)    {
      printf("Failed to store file into Online DB: %d\n",status);
      return -1; }

  return status;
}

<commit_msg>Changing defualt values and description in DA<commit_after>/*********************************************************************************
- Contact:    Michal Broz     Michal.Broz@cern.ch
- Link:       http
- Raw data test file :
- Reference run number :
- Run Type:   PEDESTAL
- DA Type:    LDC
- Number of events needed: >=1000
- Input Files:  argument list
- Output Files: local files  AD0_Histos.root, AD0_Pedestals_On.dat (Online mapping)
                FXS file     AD0_Pedestals_Off.dat (Offline mapping)
- Trigger types used: PHYSICS_EVENT
**********************************************************************************/

/**********************************************************************************
*                                                                                *
* AD Detector Algorithm used for extracting calibration parameters             *
*                                                                                *
* This program connects to the DAQ data source passed as argument.                *
* It computes calibration parameters, populates local "./AD0_Pedestals_On.dat"   *
* file, exports it to the FES, and stores it into DAQ DB                          *
* The program exits when being asked to shut down (daqDA_checkshutdown)           *
* or on End of Run event.                                                         *
* We have 32 channels instead of 16 as expected for AD0 due to the two sets of    *
* charge integrators which are used by the FEE ...                                *
*                                                                                *
***********************************************************************************/

// DATE
#include "event.h"
#include "monitor.h"
#include "daqDA.h"

//AliRoot
#include <AliADConst.h>
#include <AliADRawStream.h>
#include <AliRawReaderDate.h>
#include <AliRawReader.h>
#include <AliDAQ.h>

// standard
#include <stdio.h>
#include <stdlib.h>

//ROOT
#include "TROOT.h"
#include "TPluginManager.h"
#include <TFile.h>
#include <TH1F.h>
#include <TMath.h>

/* Main routine --- Arguments: monitoring data source */

int main(int argc, char **argv) {

/* magic line from Cvetan */
  gROOT->GetPluginManager()->AddHandler("TVirtualStreamerInfo","*","TStreamerInfo","RIO","TStreamerInfo()");

  int status;
  if (argc!=2) {
     printf("Wrong number of arguments\n");
     return -1;
  }

  // Online values (using FEE channel numbering),
  // stored into local AD0_Pedestals_On.dat:
  Double_t adcMean[32];
  Double_t adcSigma[32];
  Double_t pedMean[32];
  Double_t pedSigma[32];
  // Offline values(same but ordered as in aliroot for offliners)
  // stored into AD0_Pedestals_Off.dat:
  Double_t adcMeanOff[32];
  Double_t adcSigmaOff[32];
  Double_t pedMeanOff[32];
  Double_t pedSigmaOff[32];

//___________________________________________________
// Get cuts from AD0_Pedestal_DA.config file

  Int_t    kClockMin;   // = 16;   LHC Clock Min for pedestal calculation
  Int_t    kClockMax;   // = 19;   LHC Clock Max for pedestal calculation
  Int_t    kLowCut;     // = 60;   low cut on signal distribution - to be tuned
  Int_t    kHighCut;    // = 50;   high cut on pedestal distribution - to be tuned
  Int_t    kClockMinRef;   // = 16;   LHC Clock Min for Flag checking
  Int_t    kClockMaxRef;   // = 20;   LHC Clock Max for Flag checking
  Float_t  kChi2Max; 		// = 1.  Maximum chi2

  status = daqDA_DB_getFile("AD0_Pedestal_DA.config","./AD0_Pedestal_DA.config");
  if (status) {
      printf("Failed to get Config file (AD0_Pedestal_DA.config) from DAQ DB, status=%d\n", status);
      printf("Take default values of parameters for pedestal calculation \n");
      kClockMin  =  0;
      kClockMax  =  20;
      kLowCut    =  60;
      kHighCut   =  50;
      kClockMinRef  =  0;
      kClockMaxRef  =  20;
      kChi2Max		=  100.;
  } else {
      /* open the config file and retrieve cuts */
      FILE *fpConfig = fopen("AD0_Pedestal_DA.config","r");
      int res = fscanf(fpConfig,"%d %d %d %d %d %d %f",&kClockMin,&kClockMax,&kLowCut,&kHighCut,&kClockMinRef,&kClockMaxRef,&kChi2Max);
      if(res!=7) {
	    printf("Failed to get values from Config file (AD0_Pedestal_DA.config): wrong file format - 7 integers are expected - \n");
	    kClockMin  =  0;
        kClockMax  =  20;
    	kLowCut    =  60;
        kHighCut   =  50;
      	kClockMinRef  =  0;
      	kClockMaxRef  =  20;
      	kChi2Max	  =  100.;
      }
      fclose(fpConfig);
  }

  printf("LHC Clock Min for pedestal calculation = %d; LHC Clock Max for pedestal calculation = %d; LowCut on signal = %d ; HighCut on pedestal = %d\n",
          kClockMin, kClockMax, kLowCut, kHighCut);

//___________________________________________________
// Book HISTOGRAMS - dynamics of p-p collisions -

  char     adcName[6];
  char     pedName[6];
  TH1F     *hADCname[32];
  TH1F     *hPEDname[32];

  char  texte[12];
  for (Int_t i=0; i<16; i++) {
  	for(Int_t j=0; j<2; j++){
       		sprintf(adcName,"hADC%d%d",i,j);
       		sprintf(texte,"ADC cell%d int%d",i,j);
       		hADCname[i + 16*j]  = new TH1F(adcName,texte,1024,-0.5, 1023.5);
       		sprintf(pedName,"hPED%d%d",i,j);
       		sprintf(texte,"PED cell%d int%d",i,j);
       		hPEDname[i + 16*j]  = new TH1F(pedName,texte,1024,-0.5, 1023.5);
       		}
       }
//___________________________________________________

  /* open result file to be exported to FES */
  FILE *fpLocal=NULL;
  fpLocal=fopen("./AD0_Pedestals_On.dat","w");
  if (fpLocal==NULL) {
      printf("Failed to open local result file\n");
      return -1;}

  /* open result file to be exported to FES */
  FILE *fp=NULL;
  fp=fopen("./AD0_Pedestals_Off.dat","w");
  if (fp==NULL) {
      printf("Failed to open result file\n");
      return -1;}

  /* define data source : this is argument 1 */
  status=monitorSetDataSource( argv[1] );
  if (status!=0) {
     printf("monitorSetDataSource() failed : %s\n",monitorDecodeError(status));
     return -1;
  }

  /* declare monitoring program */
  status=monitorDeclareMp( __FILE__ );
  if (status!=0) {
    printf("monitorDeclareMp() failed : %s\n",monitorDecodeError(status));
    return -1;
  }

  /* define wait event timeout - 1s max */
  monitorSetNowait();
  monitorSetNoWaitNetworkTimeout(1000);

  /* init counters on events */
  int neventsPhysics=0;
  int neventsTotal=0;

  /* loop on events (infinite) */
  for(;;) {
      struct eventHeaderStruct *event;
      eventTypeType eventT;

      /* check shutdown condition */
      if (daqDA_checkShutdown()) {break;}

      /* get next event (blocking call until timeout) */
      status=monitorGetEventDynamic((void **)&event);
      if (status==MON_ERR_EOF) {
          printf ("End of File detected\n");
      break; /* end of monitoring file has been reached */
      }

      if (status!=0) {
           printf("monitorGetEventDynamic() failed : %s\n",monitorDecodeError(status));
      break;
      }

      /* retry if got no event */
      if (event==NULL) continue;

      /* decode event */
      eventT=event->eventType;

      switch (event->eventType){

      case START_OF_RUN:
           break;

      case END_OF_RUN:
           printf("End Of Run detected\n");
           break;

      case PHYSICS_EVENT:
           neventsPhysics++;

	   AliRawReader *rawReader = new AliRawReaderDate((void*)event);

	   AliADRawStream* rawStream  = new AliADRawStream(rawReader);
	   if (rawStream->Next()) {
           for(Int_t i=0; i<16; i++) {
	   		Int_t nFlag = 0;
			for(Int_t j=kClockMinRef; j <= kClockMaxRef; j++) {  // Check flags on clock range used for pedestal calculation
		   		if((rawStream->GetBBFlag(i,j)) || (rawStream->GetBGFlag(i,j))) nFlag++;
			}
			if(nFlag == 0){       // Fill 16*2 pedestal histograms  - 2 integrators -
				Float_t sum[2] = {0.,0.};
				Float_t sumwi[2] = {0.,0.};
		   		for(Int_t j=kClockMin;j <= kClockMax;j++){
		       		Int_t integrator = rawStream->GetIntegratorFlag(i,j);
		       		Float_t pedestal = (float)(rawStream->GetPedestal(i,j));
		       		sum[integrator] += pedestal;
		   			sumwi[integrator] += 1.;
		   		}
		   		Float_t mean[2] =  {0.,0.};
		   		Float_t chi2[2] =  {0.,0.};

	   			for(int ii=0;ii<2;ii++) if(sumwi[ii]>1.e-6) mean[ii] = sum[ii] / sumwi[ii];

				for(Int_t j=kClockMin;j <= kClockMax;j++){
		       		Int_t integrator = rawStream->GetIntegratorFlag(i,j);
		       		Float_t pedestal = (float)(rawStream->GetPedestal(i,j));
		   			chi2[integrator] += (mean[integrator] - pedestal) * (mean[integrator] - pedestal);
	   			}
	   			if(chi2[0]<kChi2Max && chi2[1]<kChi2Max) {
					for(int ii=0;ii<2;ii++){
						if(mean[ii] >1.e-6) hPEDname[i + 16*ii]->Fill(mean[ii]);
					}
				}

			}
			if((rawStream->GetBBFlag(i,10)) || (rawStream->GetBGFlag(i,10))){ // Charge
		    	Int_t integrator = rawStream->GetIntegratorFlag(i,10);
		    	Float_t charge = (float)(rawStream->GetADC(i));   // Fill 16*2 ADCmax histograms
		    	hADCname[i + 16 * integrator]->Fill(charge);
			}
    	} // End loop over channels
	   }   // End : if rawstream
           delete rawStream;
           rawStream = 0x0;
           delete rawReader;
           rawReader = 0x0;
      } // end of switch on event type

      neventsTotal++;
      /* free resources */
      free(event);

      /* exit when last event received, no need to wait for TERM signal */
      if (eventT==END_OF_RUN) {
           printf("End Of Run event detected\n");
      break;
    }

  }  // loop over events

  printf("%d physics events processed\n",neventsPhysics);

//___________________________________________________________________________
//  Computes mean values, converts FEE channels into Offline AliRoot channels
//  and dumps the ordered values into the output text file for SHUTTLE

  for(Int_t i=0; i<32; i++) {
      hPEDname[i]->GetXaxis()->SetRange(0,kHighCut);
      pedMean[i]  = hPEDname[i]->GetMean();
      pedSigma[i] = hPEDname[i]->GetRMS();
      hADCname[i]->GetXaxis()->SetRange(kLowCut,1024);
      adcMean[i]  = hADCname[i]->GetMean();
      adcSigma[i] = hADCname[i]->GetRMS();
//      printf(" i = %d, %.3f %.3f %.3f %.3f\n",i,pedMean[i],pedSigma[i],adcMean[i],adcSigma[i]);
      fprintf(fpLocal," %.3f %.3f %.3f %.3f\n",pedMean[i],pedSigma[i],adcMean[i],adcSigma[i]);

      if (i < 16) {
          Int_t j = kOfflineChannel[i];;
          pedMeanOff[j]  = pedMean[i];
          pedSigmaOff[j] = pedSigma[i];
          adcMeanOff[j]  = adcMean[i];
          adcSigmaOff[j] = adcSigma[i];
	  }
      else{
          Int_t j = kOfflineChannel[i-16];
          pedMeanOff[j+16]  = pedMean[i];
          pedSigmaOff[j+16] = pedSigma[i];
          adcMeanOff[j+16]  = adcMean[i];
          adcSigmaOff[j+16] = adcSigma[i];
      }
  }

  for(Int_t j=0; j<32; j++) {
//      printf(" j = %d, %.3f %.3f %.3f %.3f\n",j,pedMeanOff[j],pedSigmaOff[j],
//                                                adcMeanOff[j],adcSigmaOff[j]);
      fprintf(fp," %.3f %.3f %.3f %.3f\n",pedMeanOff[j],pedSigmaOff[j],
                                          adcMeanOff[j],adcSigmaOff[j]);
  }

//________________________________________________________________________
// Write root file with histos for users further check - just in case -

  TFile *histoFile = new TFile("AD0_Pedestals.root","RECREATE");

  for (Int_t i=0; i<32; i++) {
       hADCname[i]->GetXaxis()->SetRange(0,1024);
       hADCname[i]->Write();
       hPEDname[i]->Write(); }

  histoFile->Close();
  delete histoFile;

//________________________________________________________________________

  /* close local result file and FXS result file*/
  fclose(fpLocal);
  fclose(fp);

  /* export result file to FES */
  status=daqDA_FES_storeFile("./AD0_Pedestals_Off.dat","AD0da_results");
  if (status)    {
      printf("Failed to export file : %d\n",status);
      return -1; }

  /* store result file into Online DB */
  status=daqDA_DB_storeFile("./AD0_Pedestals_On.dat","AD0da_results");
  if (status)    {
      printf("Failed to store file into Online DB: %d\n",status);
      return -1; }

  return status;
}

<|endoftext|>


<commit_before>/*
 * This helper library glues delegate_stock and delegate_client
 * together.
 *
 * author: Max Kellermann <mk@cm4all.com>
 */

#include "Glue.hxx"
#include "Client.hxx"
#include "Handler.hxx"
#include "Stock.hxx"
#include "stock.hxx"
#include "lease.hxx"
#include "pool.hxx"

#include <daemon/log.h>

#include <errno.h>

struct async_operation_ref;
struct StockMap;

struct DelegateGlue final : StockGetHandler {
    struct pool *pool;

    const char *path;

    StockMap *stock;
    StockItem *item;

    const struct delegate_handler *handler;
    void *handler_ctx;
    struct async_operation_ref *async_ref;

    /* virtual methods from class StockGetHandler */
    void OnStockItemReady(StockItem &item) override;
    void OnStockItemError(GError *error) override;
};

static void
delegate_socket_release(bool reuse, void *ctx)
{
    DelegateGlue *glue = (DelegateGlue *)ctx;

    delegate_stock_put(glue->stock, *glue->item, !reuse);
}

static const struct lease delegate_socket_lease = {
    .release = delegate_socket_release,
};

void
DelegateGlue::OnStockItemReady(StockItem &_item)
{
    item = &_item;

    delegate_open(delegate_stock_item_get(_item),
                  &delegate_socket_lease, this,
                  pool, path,
                  handler, handler_ctx, async_ref);
}

void
DelegateGlue::OnStockItemError(GError *error)
{
    handler->error(error, handler_ctx);
}

void
delegate_stock_open(StockMap *stock, struct pool *pool,
                    const char *helper,
                    const ChildOptions &options,
                    const char *path,
                    const struct delegate_handler *handler, void *ctx,
                    struct async_operation_ref &async_ref)
{
    auto glue = NewFromPool<DelegateGlue>(*pool);

    glue->pool = pool;
    glue->path = path;
    glue->stock = stock;
    glue->handler = handler;
    glue->handler_ctx = ctx;
    glue->async_ref = &async_ref;

    delegate_stock_get(stock, pool, helper, options, *glue, async_ref);
}
<commit_msg>delegate/Glue: add constructor<commit_after>/*
 * This helper library glues delegate_stock and delegate_client
 * together.
 *
 * author: Max Kellermann <mk@cm4all.com>
 */

#include "Glue.hxx"
#include "Client.hxx"
#include "Handler.hxx"
#include "Stock.hxx"
#include "stock.hxx"
#include "lease.hxx"
#include "pool.hxx"

#include <daemon/log.h>

#include <errno.h>

struct async_operation_ref;
struct StockMap;

struct DelegateGlue final : StockGetHandler {
    struct pool *const pool;

    const char *const path;

    StockMap *const stock;
    StockItem *item;

    const struct delegate_handler *const handler;
    void *const handler_ctx;
    struct async_operation_ref *const async_ref;

    DelegateGlue(StockMap &_stock, struct pool &_pool,
                 const char *_path,
                 const struct delegate_handler &_handler, void *_ctx,
                 struct async_operation_ref &_async_ref)
        :pool(&_pool), path(_path), stock(&_stock),
         handler(&_handler), handler_ctx(_ctx),
         async_ref(&_async_ref) {}

    /* virtual methods from class StockGetHandler */
    void OnStockItemReady(StockItem &item) override;
    void OnStockItemError(GError *error) override;
};

static void
delegate_socket_release(bool reuse, void *ctx)
{
    DelegateGlue *glue = (DelegateGlue *)ctx;

    delegate_stock_put(glue->stock, *glue->item, !reuse);
}

static const struct lease delegate_socket_lease = {
    .release = delegate_socket_release,
};

void
DelegateGlue::OnStockItemReady(StockItem &_item)
{
    item = &_item;

    delegate_open(delegate_stock_item_get(_item),
                  &delegate_socket_lease, this,
                  pool, path,
                  handler, handler_ctx, async_ref);
}

void
DelegateGlue::OnStockItemError(GError *error)
{
    handler->error(error, handler_ctx);
}

void
delegate_stock_open(StockMap *stock, struct pool *pool,
                    const char *helper,
                    const ChildOptions &options,
                    const char *path,
                    const struct delegate_handler *handler, void *ctx,
                    struct async_operation_ref &async_ref)
{
    auto glue = NewFromPool<DelegateGlue>(*pool, *stock, *pool, path,
                                          *handler, ctx, async_ref);

    delegate_stock_get(stock, pool, helper, options, *glue, async_ref);
}
<|endoftext|>