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

phigy
互关,私信。 What is mind?No matter.What is matter?Never mind.搬运于
2025-08-24 21:53:16,当前版本为作者最后更新于2024-12-27 09:52:05,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
设查询 的结果是 ,那么我们可以通过 的大小关系判断 的大小关系。
同时对于一段 相等的连续段 都是一样的,也就是说我们可以二分出一个数后面第一个不同的数。
考虑 最大值之外的数是少的,至多 个。
所以直接二分出所有最大值之外的数(实际上写成分治会更好)就可以做到大约 ,需要注意到的是我们可能需要先取 次来知道 最大值的 。
考虑二分的常数太大了,我们强制每 个一块,如此至多 个块,然后每个块做二分,做到大约 。
按随机顺序取块就可以做到期望 。
#include <bits/stdc++.h> #define i64 long long #define pii pair<int,int> using namespace std; const int REN=200000,MAXN=REN+5; int B=293; int n; pii a[MAXN]; int mx; pii ask(int i) { if(a[i].first!=0||a[i].second!=0) {return a[i];} cout<<"? "<<i<<endl; cin>>a[i].first>>a[i].second; if(a[i].first==a[i].second&&a[i].second==0) {cout<<"! "<<i<<endl;exit(0);} return a[i]; } void solve(int L,int R) { ask(L);ask(R); if(R-L==1) {return ;} if(a[L]==a[R]) {return ;} int mid=(L+R)>>1; solve(L,mid);solve(mid,R); } signed main() { int i,j,k; cin>>n; srand(114514); vector<int>tmp; for(i=0;i*B<n;i++) { int now=i*B,nxt=min(n-1,(i+1)*B); tmp.push_back(i); ask(now);ask(nxt); mx=max(mx,a[now].first+a[now].second); mx=max(mx,a[nxt].first+a[nxt].second); } random_shuffle(tmp.begin(),tmp.end()); for(int i:tmp) { int now=i*B,nxt=min(n-1,(i+1)*B); if(a[now]!=a[nxt]) {solve(now,nxt);} } return 0; }
- 1
信息
- ID
- 2820
- 时间
- 1000ms
- 内存
- 1024MiB
- 难度
- 6
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者