結果
| 問題 |
No.3271 PQ Dot Product
|
| コンテスト | |
| ユーザー |
risujiroh
|
| 提出日時 | 2025-09-12 23:51:12 |
| 言語 | C++23 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 40 ms / 1,000 ms |
| コード長 | 2,888 bytes |
| コンパイル時間 | 3,116 ms |
| コンパイル使用メモリ | 289,968 KB |
| 実行使用メモリ | 7,720 KB |
| 最終ジャッジ日時 | 2025-09-12 23:51:25 |
| 合計ジャッジ時間 | 9,150 ms |
|
ジャッジサーバーID (参考情報) |
judge3 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 46 |
ソースコード
#if __INCLUDE_LEVEL__ == 0
#include __BASE_FILE__
int64_t Go(int64_t n, int64_t a1, int64_t b1, int64_t a2, int64_t b2) {
assert(n >= 0);
// naive
int64_t ret = 0;
ret += a1 * a2 * n * (n - 1) * (2 * n - 1) / 6;
ret += (a1 * b2 + b1 * a2) * n * (n - 1) / 2;
ret += b1 * b2 * n;
return ret;
}
void Solve(int n, int64_t K) {
auto can = [&](int64_t dot, int l, int min_val, int max_val) {
int64_t min_dot = dot + Go(n - l, -1, n - l, 1, min_val);
int64_t max_dot = dot + Go(n - l, -1, n - l, -1, max_val);
return min_dot <= K && K <= max_dot;
};
vector<int> ans(n);
int min_val = 1;
int max_val = n;
int64_t dot = 0;
for (int l : Rep(0, n)) {
if (!can(dot, l, min_val, max_val)) {
OUT("No");
return;
}
if (n - l <= 5) {
iota(ans.begin() + l, ans.end(), min_val);
do {
int64_t cur_dot = dot;
for (int i : Rep(l, n)) {
cur_dot += int64_t(n - i) * ans[i];
}
if (cur_dot == K) {
dot = cur_dot;
break;
}
} while (next_permutation(ans.begin() + l, ans.end()));
assert(dot == K);
break;
}
if (can(dot + int64_t(n - l) * min_val, l + 1, min_val + 1, max_val)) {
ans[l] = min_val++;
} else if (can(dot + int64_t(n - l) * max_val, l + 1, min_val, max_val - 1)) {
ans[l] = max_val--;
} else {
assert(false);
}
dot += int64_t(n - l) * ans[l];
}
assert(dot == K);
OUT("Yes");
OUT(Rev(Rep1(1, n)));
OUT(ans);
}
void Solve() {
int n;
int64_t K;
IN(n, K);
if (n == 3 && K == 12) {
OUT("No");
return;
}
Solve(n, K);
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
Solve();
}
#elif __INCLUDE_LEVEL__ == 1
#include <bits/stdc++.h>
template <class T> concept MyRange = std::ranges::range<T> && !std::convertible_to<T, std::string_view>;
template <class T> concept MyTuple = std::__is_tuple_like<T>::value && !MyRange<T>;
namespace std {
istream& operator>>(istream& is, MyRange auto&& r) {
for (auto&& e : r) is >> e;
return is;
}
istream& operator>>(istream& is, MyTuple auto&& t) {
apply([&](auto&... xs) { (is >> ... >> xs); }, t);
return is;
}
ostream& operator<<(ostream& os, MyRange auto&& r) {
auto sep = "";
for (auto&& e : r) os << exchange(sep, " ") << e;
return os;
}
ostream& operator<<(ostream& os, MyTuple auto&& t) {
auto sep = "";
apply([&](auto&... xs) { ((os << exchange(sep, " ") << xs), ...); }, t);
return os;
}
} // namespace std
using namespace std;
#define Rev views::reverse
#define Rep(...) [](int l, int r) { return views::iota(min(l, r), r); }(__VA_ARGS__)
#define Rep1(...) [](int l, int r) { return Rep(l, r + 1); }(__VA_ARGS__)
#define IN(...) (cin >> forward_as_tuple(__VA_ARGS__))
#define OUT(...) (cout << forward_as_tuple(__VA_ARGS__) << '\n')
#endif // __INCLUDE_LEVEL__ == 1
risujiroh