QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#226152#7613. Inverse Problemhos_lyricAC ✓26374ms861528kbC++147.9kb2023-10-25 16:58:162023-10-25 16:58:31

Judging History

你现在查看的是最新测评结果

  • [2023-10-25 16:58:31]
  • 评测
  • 测评结果:AC
  • 用时:26374ms
  • 内存:861528kb
  • [2023-10-25 16:58:16]
  • 提交

answer

#include <cassert>
#include <cmath>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <bitset>
#include <complex>
#include <deque>
#include <functional>
#include <iostream>
#include <limits>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>

using namespace std;

using Int = long long;

template <class T1, class T2> ostream &operator<<(ostream &os, const pair<T1, T2> &a) { return os << "(" << a.first << ", " << a.second << ")"; };
template <class T> ostream &operator<<(ostream &os, const vector<T> &as) { const int sz = as.size(); os << "["; for (int i = 0; i < sz; ++i) { if (i >= 256) { os << ", ..."; break; } if (i > 0) { os << ", "; } os << as[i]; } return os << "]"; }
template <class T> void pv(T a, T b) { for (T i = a; i != b; ++i) cerr << *i << " "; cerr << endl; }
template <class T> bool chmin(T &t, const T &f) { if (t > f) { t = f; return true; } return false; }
template <class T> bool chmax(T &t, const T &f) { if (t < f) { t = f; return true; } return false; }
#define COLOR(s) ("\x1b[" s "m")

////////////////////////////////////////////////////////////////////////////////
template <unsigned M_> struct ModInt {
  static constexpr unsigned M = M_;
  unsigned x;
  constexpr ModInt() : x(0U) {}
  constexpr ModInt(unsigned x_) : x(x_ % M) {}
  constexpr ModInt(unsigned long long x_) : x(x_ % M) {}
  constexpr ModInt(int x_) : x(((x_ %= static_cast<int>(M)) < 0) ? (x_ + static_cast<int>(M)) : x_) {}
  constexpr ModInt(long long x_) : x(((x_ %= static_cast<long long>(M)) < 0) ? (x_ + static_cast<long long>(M)) : x_) {}
  ModInt &operator+=(const ModInt &a) { x = ((x += a.x) >= M) ? (x - M) : x; return *this; }
  ModInt &operator-=(const ModInt &a) { x = ((x -= a.x) >= M) ? (x + M) : x; return *this; }
  ModInt &operator*=(const ModInt &a) { x = (static_cast<unsigned long long>(x) * a.x) % M; return *this; }
  ModInt &operator/=(const ModInt &a) { return (*this *= a.inv()); }
  ModInt pow(long long e) const {
    if (e < 0) return inv().pow(-e);
    ModInt a = *this, b = 1U; for (; e; e >>= 1) { if (e & 1) b *= a; a *= a; } return b;
  }
  ModInt inv() const {
    unsigned a = M, b = x; int y = 0, z = 1;
    for (; b; ) { const unsigned q = a / b; const unsigned c = a - q * b; a = b; b = c; const int w = y - static_cast<int>(q) * z; y = z; z = w; }
    assert(a == 1U); return ModInt(y);
  }
  ModInt operator+() const { return *this; }
  ModInt operator-() const { ModInt a; a.x = x ? (M - x) : 0U; return a; }
  ModInt operator+(const ModInt &a) const { return (ModInt(*this) += a); }
  ModInt operator-(const ModInt &a) const { return (ModInt(*this) -= a); }
  ModInt operator*(const ModInt &a) const { return (ModInt(*this) *= a); }
  ModInt operator/(const ModInt &a) const { return (ModInt(*this) /= a); }
  template <class T> friend ModInt operator+(T a, const ModInt &b) { return (ModInt(a) += b); }
  template <class T> friend ModInt operator-(T a, const ModInt &b) { return (ModInt(a) -= b); }
  template <class T> friend ModInt operator*(T a, const ModInt &b) { return (ModInt(a) *= b); }
  template <class T> friend ModInt operator/(T a, const ModInt &b) { return (ModInt(a) /= b); }
  explicit operator bool() const { return x; }
  bool operator==(const ModInt &a) const { return (x == a.x); }
  bool operator!=(const ModInt &a) const { return (x != a.x); }
  friend std::ostream &operator<<(std::ostream &os, const ModInt &a) { return os << a.x; }
};
////////////////////////////////////////////////////////////////////////////////

constexpr unsigned MO = 1000000007;
using Mint = ModInt<MO>;
using Mint1 = ModInt<MO - 1>;


constexpr int S = ceil(sqrt(MO));
constexpr Mint G = 5;
Mint H;
pair<unsigned, int> baby[S + 1];
void init() {
  H = 1;
  for (int i = 0; i < S; ++i) {
    baby[i] = make_pair(H.x, i);
    H *= G;
  }
  sort(baby, baby + S);
  baby[S] = make_pair(~0U, -1);
  H = H.inv();
}
int modLog(Mint a) {
  for (int i = 0; i < S; ++i) {
    const int pos = lower_bound(baby, baby + S, make_pair(a.x, -1)) - baby;
    if (baby[pos].first == a.x) {
      return i * S + baby[pos].second;
    }
    a *= H;
  }
  assert(false);
}

constexpr int LIM = 210;
int lpf[LIM];
Mint1 LOG[LIM];

int T;
vector<Mint> R;
vector<Mint1> logR;
vector<int> Ns;
vector<vector<pair<int, int>>> ANSs;

int N;
Mint1 W[LIM];


constexpr int K = 5;
bitset<MO - 1> has;
vector<pair<unsigned, __int128>> small[LIM], large[LIM];

#ifdef LOCAL
int counterSmall, counterLarge;
#endif

void dfsSmall(int m, int last, Mint1 w, __int128 p) {
#ifdef LOCAL
++counterSmall;
#endif
  small[N - 2 - m].emplace_back(w.x, p);
  for (int a = min(m, last); a >= 1; --a) {
    dfsSmall(m - a, a, w + W[a], p << a | 1);
  }
}
void dfsLarge(int m, int last, Mint1 w, __int128 p) {
#ifdef LOCAL
++counterLarge;
#endif
  large[N - 2 - m].emplace_back(w.x, p);
  for (int a = min(m, last); a > K; --a) {
    dfsLarge(m - a, a, w + W[a], p << a | 1);
  }
}

void recover(int t, __int128 p0, __int128 p1) {
  vector<int> ds;
  for (const __int128 p : {p0, p1}) {
    int a = 0;
    for (__int128 q = p; q >>= 1; ) {
      ++a;
      if (q & 1) {
        ds.push_back(a);
        a = 0;
      }
    }
  }
  sort(ds.begin(), ds.end(), greater<int>{});
  ds.resize(N - 1, 0);
  Ns[t] = N;
  int b = 1;
  for (int a = 0; a < N; ++a) {
    const int deg = a ? ds[a - 1] : 1;
    for (int j = 0; j < deg; ++j) {
      ANSs[t].emplace_back(a, b);
      ++b;
    }
  }
  assert(b == N);
}

void solve() {
  if (N == 1) {
    for (int t = 0; t < T; ++t) if (!Ns[t]) {
      if (R[t] == 1) {
        Ns[t] = 1;
      }
    }
    return;
  }
  
  // rooted degree d: (N-2)(N-3)...
  W[0] = 0;
  for (int d = 0; d < N - 2; ++d) {
    W[d + 1] = W[d] + LOG[N - 2 - d];
  }
  
#ifdef LOCAL
counterSmall=counterLarge=0;
#endif
  for (int n = 0; n <= N - 2; ++n) {
    small[n].clear();
    large[n].clear();
  }
  dfsSmall(N - 2, K, 0, 1);
  dfsLarge(N - 2, N - 2, 0, 1);
#ifdef LOCAL
cerr<<"N = "<<N<<": counterSmall = "<<counterSmall<<", counterLarge = "<<counterLarge<<endl;
#endif
  
  for (int n0 = 0; n0 <= N - 2; ++n0) {
    const int n1 = N - 2 - n0;
    for (const auto &wp0 : small[n0]) has.set(wp0.first);
    for (int t = 0; t < T; ++t) if (!Ns[t]) {
      const Mint1 tar = logR[t] - LOG[N] - LOG[N - 1];
      for (const auto &wp1 : large[n1]) {
        const unsigned key = (tar - wp1.first).x;
        if (has[key]) {
          for (const auto &wp0 : small[n0]) if (wp0.first == key) {
            recover(t, wp0.second, wp1.second);
            break;
          }
          break;
        }
      }
    }
    for (const auto &wp0 : small[n0]) has.reset(wp0.first);
  }
}

int main() {
  init();
  for (int p = 2; p < LIM; ++p) lpf[p] = p;
  for (int p = 2; p < LIM; ++p) if (lpf[p] == p) {
    for (int n = p; n < LIM; n += p) chmin(lpf[n], p);
  }
  LOG[1] = 0;
  for (int n = 2; n < LIM; ++n) {
    const int p = lpf[n];
    LOG[n] = (n == p) ? modLog(n) : (LOG[p] + LOG[n / p]);
  }
// for(int n=1;n<LIM;++n)assert(G.pow(LOG[n].x)==n);
  
  for (; ~scanf("%d", &T); ) {
    R.resize(T);
    for (int t = 0; t < T; ++t) {
      scanf("%u", &R[t].x);
    }
    
    logR.assign(T, 0);
    for (int t = 0; t < T; ++t) {
      logR[t] = modLog(R[t]);
    }
    Ns.assign(T, 0);
    ANSs.assign(T, {});
    for (N = 1; N <= 129; ++N) {
      bool yet = false;
      for (int t = 0; t < T; ++t) yet = yet || !Ns[t];
      if (!yet) break;
      solve();
    }
    
    for (int t = 0; t < T; ++t) {
      printf("%d\n", Ns[t]);
      for (const auto &e : ANSs[t]) {
        printf("%d %d\n", e.first + 1, e.second + 1);
      }
    }
  }
  return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 63ms
memory: 88012kb

input:

4
2
360
1
509949433

output:

2
1 2
5
1 2
2 3
2 4
3 5
1
10
1 2
2 3
3 4
4 5
5 6
6 7
7 8
8 9
9 10

result:

ok OK (4 test cases)

Test #2:

score: 0
Accepted
time: 12670ms
memory: 861528kb

input:

9
185396120
468170792
837583517
696626231
338497514
762842660
800028852
928391161
733524004

output:

14
1 2
2 3
2 4
3 5
3 6
4 7
5 8
6 9
7 10
8 11
9 12
10 13
11 14
122
1 2
2 3
2 4
2 5
2 6
2 7
2 8
2 9
2 10
2 11
2 12
2 13
2 14
2 15
2 16
2 17
2 18
2 19
2 20
2 21
2 22
2 23
2 24
2 25
2 26
2 27
2 28
2 29
2 30
2 31
3 32
3 33
3 34
3 35
3 36
3 37
3 38
3 39
3 40
3 41
3 42
3 43
3 44
3 45
4 46
4 47
4 48
4 49
4 ...

result:

ok OK (9 test cases)

Test #3:

score: 0
Accepted
time: 26374ms
memory: 859660kb

input:

10
338497514
733524004
447182954
415993605
453460670
50499055
648088551
986982752
907925397
315315230

output:

124
1 2
2 3
2 4
2 5
2 6
2 7
2 8
2 9
2 10
2 11
2 12
2 13
2 14
2 15
2 16
2 17
2 18
2 19
2 20
2 21
2 22
2 23
2 24
2 25
2 26
2 27
2 28
2 29
2 30
2 31
2 32
2 33
2 34
2 35
2 36
3 37
3 38
3 39
3 40
3 41
3 42
3 43
3 44
3 45
3 46
3 47
3 48
3 49
3 50
3 51
4 52
4 53
4 54
4 55
4 56
4 57
4 58
4 59
4 60
5 61
5 62...

result:

ok OK (10 test cases)

Test #4:

score: 0
Accepted
time: 1981ms
memory: 272912kb

input:

10
1
2
3
4
5
6
7
8
9
10

output:

1
2
1 2
102
1 2
2 3
2 4
2 5
2 6
2 7
2 8
2 9
2 10
2 11
2 12
2 13
2 14
2 15
2 16
2 17
2 18
2 19
2 20
2 21
2 22
2 23
2 24
2 25
3 26
3 27
3 28
3 29
3 30
3 31
3 32
3 33
3 34
3 35
3 36
3 37
3 38
3 39
3 40
3 41
3 42
3 43
4 44
4 45
4 46
4 47
4 48
4 49
4 50
4 51
4 52
4 53
4 54
4 55
4 56
5 57
5 58
5 59
5 60
5...

result:

ok OK (10 test cases)

Test #5:

score: 0
Accepted
time: 649ms
memory: 173424kb

input:

10
269199917
392009324
753889928
751355133
472639410
132096559
331333826
40414701
72847302
475706026

output:

55
1 2
2 3
2 4
2 5
2 6
2 7
2 8
2 9
2 10
2 11
2 12
2 13
2 14
2 15
2 16
2 17
2 18
2 19
2 20
2 21
2 22
2 23
2 24
2 25
2 26
2 27
2 28
2 29
2 30
2 31
2 32
2 33
2 34
2 35
2 36
2 37
2 38
2 39
2 40
2 41
2 42
2 43
2 44
2 45
2 46
2 47
2 48
2 49
2 50
2 51
2 52
2 53
2 54
2 55
84
1 2
2 3
2 4
2 5
2 6
2 7
2 8
3 9
...

result:

ok OK (10 test cases)

Extra Test:

score: 0
Extra Test Passed