1 条题解
-
0
自动搬运
来自洛谷,原作者为

ottora
汨羅の渕に波騷ぎ 巫山の雲は亂れ飛ぶ搬运于
2025-08-24 22:55:44,当前版本为作者最后更新于2024-02-28 13:14:25,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
考虑随机化。
先随机 次询问,再枚举序列长度 并检查是否合法。
注意到长度为 的循环单峰排列是 的(A060354),因此当 时即可求出唯一的 。
之后倍增求最大值是简单的。
期望询问次数 ,实际上非常优秀,在本题数据范围下几乎不超过 次询问。
代码
#include <bits/stdc++.h> using namespace std; int ask(int); int cheat(); vector<int> B; vector<int64_t> X; vector<pair<int, int>> V; bool check(int n, int q){ V.clear(); for(int i = 0; i < q; i++) V.emplace_back(X[i] % n, B[i]); sort(V.begin(), V.end()); for(int i = 0; i < q; i++) if(V[i].first == (V[(i + 1) % q].first) && V[i].second != (V[(i + 1) % q].second)) return 0; V.erase(unique(V.begin(), V.end()), V.end()), q = V.size(); if(q > 2) for(int i = 0; i < q; i++) if(V[i].second == V[(i + 1) % q].second && V[i].second == V[(i + 2) % q].second) return 0; int mx = 0, mn = 0; for(int i = 0; i < q; i++) if(V[i].second > V[mx].second) mx = i; for(int i = 0; i < q; i++) if(V[i].second < V[mn].second) mn = i; for(int i = mn, lst = INT_MIN; i != mx; ++i >= q && (i = 0)) if(V[i].second < lst) return 0; else lst = V[i].second; for(int i = mx, lst = INT_MAX; i != mn; ++i >= q && (i = 0)) if(V[i].second > lst) return 0; else lst = V[i].second; return 1; } int buer(int){ mt19937 rnd(time(0)); vector<int> Ans; for(int i = 2; i <= 1000000; i++) Ans.push_back(i); int64_t x = 0; for(int q = 1; Ans.size() > 1; q++){ int k = rnd() % 1000000000 + 1; X.push_back(x += k), B.push_back(ask(k)); if(q > 5){ vector<int> Now; for(int i: Ans) if(check(i, q)) Now.push_back(i); Ans = Now; } } int n = Ans.back(), id = 0; for(int i = 0; i < (int)X.size(); i++) if(B[i] > B[id]) id = i; int p = ask((X[id] - x) % n + n), q = ask(1); id = (X[id] + 1) % n; if(p < q){ int v = q; for(int k = 20; k >= 0; k--){ p = ask(1 << k), q = ask(1); if(v < p && p < q) id = (id + (1 << k) + 1) % n, v = q; else ask((n - (1 << k) - 1) % n + n); } return max(v, ask(1)); } else { int v = q; for(int k = 20; k >= 0; k--){ p = ask((n - (1 << k)) % n + n), q = ask(n - 1); if(v < p && p < q) id = (id + n * 2 - (1 << k) - 1) % n, v = q; else ask((1 << k) + 1); } return max(v, ask(n - 1)); } return 0; }
- 1
信息
- ID
- 9655
- 时间
- 1500ms
- 内存
- 1024MiB
- 难度
- 7
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者