QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#405451 | #7613. Inverse Problem | ucup-team3215 | TL | 0ms | 3556kb | C++20 | 2.2kb | 2024-05-05 23:00:32 | 2024-05-05 23:00:34 |
Judging History
answer
#include <algorithm>
#include <cstdint>
#include <iostream>
#include <numeric>
#include <unordered_map>
#include <vector>
using namespace std;
constexpr int mod = 1e9 + 7;
auto& mul(auto&& a, auto b) { return a = a * (uint64_t) b % mod; }
int inv(int a) { for (int r = 1, b = mod - 2; ; b /= 2, mul(a, a)) if (!b) return r; else if (b % 2) mul(r, a); }
using namespace std;
vector<unordered_map<int, vector<int>>> even(1);
vector<int> inv_(1);
void gen_even(int n0, int n, int c, int p, auto&& cur) {
even[n0 - n].emplace(p, cur);
for (; c > 0; c -= 2) if (c <= n) {
int np = p;
for (int i = 0; i < c; ++i) mul(np, inv_[n0 - i]);
cur.push_back(c);
gen_even(n0, n - c, c, np, cur);
cur.pop_back();
}
}
vector<int> qs;
vector<vector<int>> ans;
void solve(int n0, int n, int c, int p, auto&& cur) {
if (n % 2 == 0)
for (int i = 0; i < qs.size(); ++i) if (auto it = even[n].begin(); ans[i].empty() && (it = even[n].find(mul(+p, qs[i]))) != even[n].end()) {
ans[i] = cur;
ans[i].insert(ans[i].end(), it->second.begin(), it->second.end());
}
for (; c > 0; c -= 2) if (c <= n) {
int np = p;
for (int i = 0; i < c; ++i) mul(np, n0 - i);
cur.push_back(c);
solve(n0, n - c, c, np, cur);
cur.pop_back();
}
}
int main() {
int tc; cin >> tc;
qs.resize(tc);
ans.resize(tc);
for (int i = 0; i < tc; ++i) {
cin >> qs[i];
if (qs[i] == 1) ans[i] = {-1};
else if (qs[i] == 2) ans[i] = {-1};
qs[i] = inv(qs[i]);
}
for (int n = 1, done = 0; !done++; ++n) {
inv_.push_back(inv(n));
even.push_back({});
for (auto& x: even) x.clear();
gen_even(n, n, n + n % 2, 1, vector<int>{});
solve(n, n, n - n % 2 + 1, mul(n + 1, n + 2), vector<int>{});
for (int i = 0; i < tc; ++i) done &= !ans[i].empty();
}
for (int i = 0; i < tc; ++i) {
if (qs[i] == 1) cout << "1\n";
else {
if (ans[i][0] == -1) ans[i] = {};
cout << accumulate(ans[i].begin(), ans[i].end(), 0) + 2 << '\n' << "1 2\n";
for (int j = 0, k = 2; j < ans[i].size(); ++j)
while (ans[i][j]--) cout << j + 1 << ' ' << ++k << '\n';
}
}
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 0ms
memory: 3556kb
input:
4 2 360 1 509949433
output:
2 1 2 5 1 2 1 3 2 4 2 5 1 10 1 2 1 3 2 4 3 5 4 6 5 7 6 8 7 9 8 10
result:
ok OK (4 test cases)
Test #2:
score: -100
Time Limit Exceeded
input:
9 185396120 468170792 837583517 696626231 338497514 762842660 800028852 928391161 733524004