Submission #673521

#TimeUsernameProblemLanguageResultExecution timeMemory
673521peijarMisspelling (JOI22_misspelling)C++17
60 / 100
4064 ms147900 KiB
#include <bits/stdc++.h>
#define int long long
using namespace std;

template <const int32_t MOD> struct ModInt {
  int32_t x;
  ModInt() : x(0) {}
  ModInt(long long u) : x(u % MOD) {
    if (x < 0)
      x += MOD;
  }
  friend bool operator==(const ModInt &a, const ModInt &b) {
    return a.x == b.x;
  }
  friend bool operator!=(const ModInt &a, const ModInt &b) {
    return a.x != b.x;
  }
  friend bool operator<(const ModInt &a, const ModInt &b) { return a.x < b.x; }
  friend bool operator>(const ModInt &a, const ModInt &b) { return a.x > b.x; }
  friend bool operator<=(const ModInt &a, const ModInt &b) {
    return a.x <= b.x;
  }
  friend bool operator>=(const ModInt &a, const ModInt &b) {
    return a.x >= b.x;
  }
  static ModInt sign(long long k) {
    return ((k & 1) ? ModInt(MOD - 1) : ModInt(1));
  }

  ModInt &operator+=(const ModInt &m) {
    x += m.x;
    if (x >= MOD)
      x -= MOD;
    return *this;
  }
  ModInt &operator-=(const ModInt &m) {
    x -= m.x;
    if (x < 0LL)
      x += MOD;
    return *this;
  }
  ModInt &operator*=(const ModInt &m) {
    x = (1LL * x * m.x) % MOD;
    return *this;
  }

  friend ModInt operator-(const ModInt &a) {
    ModInt res(a);
    if (res.x)
      res.x = MOD - res.x;
    return res;
  }
  friend ModInt operator+(const ModInt &a, const ModInt &b) {
    return ModInt(a) += ModInt(b);
  }
  friend ModInt operator-(const ModInt &a, const ModInt &b) {
    return ModInt(a) -= ModInt(b);
  }
  friend ModInt operator*(const ModInt &a, const ModInt &b) {
    return ModInt(a) *= ModInt(b);
  }

  static long long fp(long long u, long long k) {
    long long res = 1LL;
    while (k > 0LL) {
      if (k & 1LL)
        res = (res * u) % MOD;
      u = (u * u) % MOD;
      k /= 2LL;
    }
    return res;
  }

  static constexpr int mod() { return MOD; }

  ModInt fastpow(long long k) { return ModInt(fp(x, k)); }
  ModInt inv() {
    assert(x);
    return ModInt(fp(x, MOD - 2));
  }
  ModInt &operator/=(const ModInt &m) { return *this *= ModInt(m).inv(); }
  friend ModInt operator/(const ModInt &a, const ModInt &b) {
    return ModInt(a) *= ModInt(b).inv();
  }

  friend ostream &operator<<(ostream &out, const ModInt &a) {
    return out << a.x;
  }
  friend istream &operator>>(istream &in, ModInt &a) { return in >> a.x; }
};

const int MOD = 1e9 + 7;
using Mint = ModInt<MOD>;

template <class T> class Fenwick {
public:
  int lim;
  vector<T> bit;

  Fenwick(int n) : lim(n + 1), bit(lim) {}

  void upd(int pos, T val) {
    for (pos++; pos < lim; pos += pos & -pos)
      bit[pos] += val;
  }

  T sum(int r) { // < r
    T ret = 0;
    for (; r; r -= r & -r)
      ret += bit[r];
    return ret;
  }

  T sum(int l, int r) { // [l, r)
    if (l >= r)
      return T(0);
    return sum(r) - sum(l);
  }
};

struct Contrainte {
  int L, R;
  bool inc;
};

signed main(void) {
  ios_base::sync_with_stdio(false);
  cin.tie(0);

  int longueur, nbContraintes;
  cin >> longueur >> nbContraintes;

  vector<Contrainte> contraintes(nbContraintes);

  for (int i = 0; i < nbContraintes; ++i) {
    int A, B;
    cin >> A >> B;
    --A, --B;
    if (A < B)
      contraintes[i] = {A, B, false};
    else
      contraintes[i] = {B, A, true};
  }

  vector<vector<int>> startAt(longueur);
  for (int i = 0; i < nbContraintes; ++i)
    startAt[contraintes[i].L].push_back(i);

  vector<array<Mint, 26>> dp(longueur);
  dp[0].fill(1);

  priority_queue<pair<int, int>> pqInc, pqDec;

  vector<Fenwick<Mint>> fens;
  for (int i = 0; i < 26; ++i) {
    fens.emplace_back(longueur);
    fens[i].upd(0, 1);
  }

  for (int i = 1; i < longueur; ++i) {
    for (int iContrainte : startAt[i - 1]) {
      if (contraintes[iContrainte].inc)
        pqInc.emplace(contraintes[iContrainte].L, iContrainte);
      else
        pqDec.emplace(contraintes[iContrainte].L, iContrainte);
    }

    while (!pqInc.empty() and contraintes[pqInc.top().second].R < i)
      pqInc.pop();
    while (!pqDec.empty() and contraintes[pqDec.top().second].R < i)
      pqDec.pop();

    int LInc = pqInc.empty() ? -1 : pqInc.top().first,
        LDec = pqDec.empty() ? -1 : pqDec.top().first;
    for (int nxt = 0; nxt < 26; ++nxt) {
      dp[i][nxt] = 0;
      for (int old = 0; old < nxt; ++old)
        dp[i][nxt] += fens[old].sum(LDec + 1, i);
      for (int old = nxt + 1; old < 26; ++old)
        dp[i][nxt] += fens[old].sum(LInc + 1, i);
      fens[nxt].upd(i, dp[i][nxt]);
    }
  }
  Mint ret = 0;
  for (int i = 0; i < longueur; ++i)
    ret += accumulate(dp[i].begin(), dp[i].end(), Mint(0));
  cout << ret << endl;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...