[CF1526F] Median Queries(交互 / 构造)
题面
这是一道交互题。
有一个未知的长度为
N
\tt N
N 的排列
P
\tt P
P,已知
P
1
<
P
2
\tt P_1 < P_2
P1<P2 。
每次询问格式为 “
?
a
b
c
\tt?~a~b~c
? a b c ”,返回值为三元组
{
∣
P
a
−
P
b
∣
,
∣
P
b
−
P
c
∣
,
∣
P
a
−
P
c
∣
}
\tt \{|P_a-P_b|,|P_b-P_c|,|P_a-P_c|\}
{∣Pa−Pb∣,∣Pb−Pc∣,∣Pa−Pc∣} 的中位数。
在至多
2
n
+
420
\tt 2n+420
2n+420 次询问后,输出排列
P
\tt P
P,格式为 “
!
P
1
P
2
…
P
N
\tt!~P_1~P_2~\dots~P_N
! P1 P2 … PN ”。
然后每组数据会返回一个数,为
1
\tt1
1 则答案正确,为
−
1
\tt-1
−1 则错误,不要忘了输入这个数。
一共
t
(
1
≤
t
≤
1000
)
\tt t(1\leq t\leq1000)
t(1≤t≤1000) 组数据,保证
20
≤
N
≤
1
0
5
,
∑
N
≤
1
0
5
20\leq N\leq 10^5,\tt \sum N\leq 10^5
20≤N≤105,∑N≤105。
题解
有两种各占优势的做法。
Solution #1
首先,返回该三元组的中位数,相当于:若
P
a
>
P
b
>
P
c
\tt P_a>P_b>P_c
Pa>Pb>Pc,则返回
max
{
P
a
−
P
b
,
P
b
−
P
c
}
\tt\max\{P_a-P_b,P_b-P_c\}
max{Pa−Pb,Pb−Pc}。
有了这个简化,才能更好地继续推。
该解法的核心在于:如果已经知道了
1
\tt1
1 和
2
\tt2
2 的位置(假设为
P
A
,
P
B
\tt P_A,P_B
PA,PB),那么可以在
n
−
2
\tt n-2
n−2 次操作后,确定整个排列。也就是分别询问
{
A
,
B
,
i
}
\tt\{A,B,i\}
{A,B,i},所得值(
q
u
e
r
y
(
A
,
B
,
i
)
\tt query(A,B,i)
query(A,B,i))
+
2
\tt+2
+2 便是
P
i
\tt P_i
Pi 了。
问题是怎么获得
1
\tt1
1 和
2
\tt2
2 的位置,或者说,也可以获得
N
\tt N
N 和
N
−
1
\tt N-1
N−1 的位置,总之通过
P
1
<
P
2
\tt P_1<P_2
P1<P2 确定最终答案。
经过一段尝试,我们发现,如果找到这么两个位置
a
\tt a
a 和
b
\tt b
b ,满足
∣
P
a
−
P
b
∣
≤
N
−
4
3
\tt|P_a-P_b|\leq \frac{N-4}{3}
∣Pa−Pb∣≤3N−4 ,处理出所有的
q
[
i
]
=
q
u
e
r
y
(
a
,
b
,
i
)
\tt q[i]=query(a,b,i)
q[i]=query(a,b,i) ,那么
q
[
i
]
\tt q[i]
q[i] 最大的
i
\tt i
i 就是
1
\tt1
1 或者
N
\tt N
N 的位置,
q
[
i
]
\tt q[i]
q[i] 严格次大的
i
\tt i
i 就是
2
\tt2
2 或者
N
−
1
\tt N-1
N−1 的位置。这样只需要多进行
N
−
2
\tt N-2
N−2 次操作。
那么,在剩下的
424
\tt424
424 次操作内,我们需要解决两个问题:
- 找到这样的位置
a
,
b
\tt a,b
a,b 。
- 找到
1
\tt1
1 和
2
\tt2
2 的或者
N
\tt N
N 和
N
−
1
\tt N-1
N−1 的位置
A
,
B
\tt A,B
A,B 。
找 a b:
我们可以证明:对于任意
13
\tt13
13 个位置,总存在
3
\tt3
3 个位置
x
,
y
,
z
\tt x,y,z
x,y,z ,满足
q
u
e
r
y
(
x
,
y
,
z
)
≤
n
−
4
6
\tt query(x,y,z)\leq\frac{n-4}{6}
query(x,y,z)≤6n−4(
⇒
max
{
∣
P
x
−
P
y
∣
,
∣
P
y
−
P
z
∣
,
∣
P
x
−
P
z
∣
}
≤
n
−
4
3
\tt\Rightarrow \max\{|P_x-P_y|,|P_y-P_z|,|P_x-P_z|\}\leq\frac{n-4}{3}
⇒max{∣Px−Py∣,∣Py−Pz∣,∣Px−Pz∣}≤3n−4)。
可以用反证法进行证明,即假设存在某
13
\tt13
13 个位置,满足
∀
{
x
,
y
,
z
}
,
max
{
∣
P
x
−
P
y
∣
,
∣
P
y
−
P
z
∣
,
∣
P
x
−
P
z
∣
}
>
n
−
4
3
\tt\forall \{x,y,z\},\max\{|P_x-P_y|,|P_y-P_z|,|P_x-P_z|\}>\frac{n-4}{3}
∀{x,y,z},max{∣Px−Py∣,∣Py−Pz∣,∣Px−Pz∣}>3n−4 。贪心地填数进去,你就会发现,刚好到
13
\tt13
13 个时,你就满足不了条件了。所以这种情况不存在,假设不成立。
找这
3
\tt3
3 个位置,需要枚举
(
13
3
)
=
286
\tt{13\choose3}=286
(313)=286 种情况,完全足够。
找到这样的
3
\tt3
3 个位置时,任选两个就可以作
a
,
b
\tt a,b
a,b 了。
找 A B:
我们会发现,假如你确定了某个
q
[
i
]
\tt q[i]
q[i] 最大的
A
\tt A
A 作为
1
\tt1
1 的位置,那么还是有两个位置可能为
2
\tt2
2 ,一个是真
2
\tt2
2 ,一个是
N
−
1
\tt N-1
N−1 ,令其分别为
B
1
,
B
2
\tt B_1,B_2
B1,B2 ,我们稍稍归纳一下就会发现:
q
u
e
r
y
(
A
,
B
1
,
a
)
≤
q
u
e
r
y
(
A
,
B
2
,
a
)
q
u
e
r
y
(
A
,
B
1
,
b
)
≤
q
u
e
r
y
(
A
,
B
2
,
b
)
{\tt query(A,B_1,a)\leq query(A,B_2,a)}\\ {\tt query(A,B_1,b)\leq query(A,B_2,b)}
query(A,B1,a)≤query(A,B2,a)query(A,B1,b)≤query(A,B2,b)
而且最多只有一个取等。因此便可以把
B
1
\tt B_1
B1 判断出来了。
CODE
#include<cstdio>
#include<vector>
#include<cmath>
#include<ctime>
#include<queue>
#include<map>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define MAXN 100005
#define DB double
#define LL long long
#define ENDL putchar('\n')
#define lowbit(x) ((-x) & (x))
#define INF 0x3f3f3f3f
LL read() {
LL f=1,x=0;char s = getchar();
while(s < '0' || s > '9') {if(s=='-')f = -f;s = getchar();}
while(s >= '0' && s <= '9') {x=x*10+(s-'0');s = getchar();}
return f * x;
}
int n,m,i,j,s,o,k;
inline int ask(int a,int b,int c) {
cout<<"? "<<a<<" "<<b<<" "<<c<<endl;
int as; cin>>as; return as;
}
int a[MAXN],p[MAXN],ar[MAXN];
vector<int> bu[MAXN];
int main() {
srand(time(0));
int T;cin>>T;
while(T --) {
cin>>n;
for(int i = 1;i <= n;i ++) bu[i].clear(),a[i] = 0,ar[i] = i;
random_shuffle(ar + 1,ar + 1 + n);
int A = 1,B = 2,C = 3,as,flag1 = 0;
for(A = 1;A <= 11;A ++) {
for(B = A+1;B <= 12;B ++) {
for(C = B+1;C <= 13;C ++) {
if((as=ask(A,B,C)) <= ((n-4)/6)) {
flag1 = 1; break;
}
}
if(flag1) break;
}
if(flag1) break;
}
int mi = n+1,ct = 1,ct2 = 0,ma = 0;
for(int i = 1;i <= n;i ++) {
if(i != A && i != B) {
a[i] = ask(A,B,i);
if(a[i] < mi) mi = a[i],ct = 1;
else if(a[i] == mi) ct ++;
if(a[i] == 2) ct2 ++;
ma = max(ma,a[i]);
bu[a[i]].push_back(i);
}
}
int H = bu[ma][0],H2 = bu[ma-1][0];
if((int)bu[ma-1].size() > 1) {
int H3 = bu[ma-1][1];
if(ask(H,H2,A) <= ask(H,H3,A) && ask(H,H2,B) <= ask(H,H3,B)) {
H2 = H2;
}
else H2 = H3;
}
p[H] = 1; p[H2] = 2;
for(int i = 1;i <= n;i ++) {
if(i != H && i != H2) {
p[i] = 2 + ask(H,H2,i);
}
}
if(p[1] > p[2]) {
for(int i = 1;i <= n;i ++) p[i] = n-p[i]+1;
}
cout<<"!";
for(int i = 1;i <= n;i ++) cout<<" "<<p[i];
cout<<endl;
int AC; cin>>AC;
}
return 0;
}
Solution #2
非常精妙的做法,不愧是
O
n
e
I
n
D
a
r
k
\tt OneInDark
OneInDark !
主要是选择两对数来进行序列
q
\tt q
q 的确定,通过
q
\tt q
q 和
q
′
\tt q'
q′ 确定原序列。这里笔者就不展开了。原博客还是写了满大页的。
[CF1526F] Median Queries(交互 / 构造)的更多相关文章
- B - Median Pyramid Easy 构造题
B - Median Pyramid Easy Time limit : 2sec / Memory limit : 256MB Score : 400 points Problem Statemen ...
- $AT2163\ Median\ Pyramid\ Easy$ 构造
正解:构造 解题报告: 传送门$QwQ$ 考虑如果有两个相邻格子是相同数字那么它们以上这两列就都会是这列数字(显然$QwQ$? 所以考虑只要构造出第$n-1$行的中心和中心右侧($or$左侧一样的$Q ...
- Gym - 100851J: Jump(交互+构造+(大胆瞎搞)))
题意:给定长度为N的01串,现在让你猜这个串,猜的次数要不超过N+500次. 每次你猜一个串,系统会返回N/2,或N,或0.当且当有N/2个位置猜对,N个位置猜对,其他. 思路:因为信息不多,没有关联 ...
- Codeforces Round #669 (Div. 2) C. Chocolate Bunny (交互,构造)
题意:有一个长度为\(n\)的隐藏序列,你最多可以询问\(2n\)次,每次可以询问\(i\)和\(j\)位置上\(p[i]\ mod\ p[j]\)的结果,询问的格式是\(?\ x\ y\),如果已经 ...
- Codeforces Round #356 (Div. 2)
A. Bear and Five Cards time limit per test 2 seconds memory limit per test 256 megabytes input stand ...
- Kafka connect快速构建数据ETL通道
摘要: 作者:Syn良子 出处:http://www.cnblogs.com/cssdongl 转载请注明出处 业余时间调研了一下Kafka connect的配置和使用,记录一些自己的理解和心得,欢迎 ...
- Educational Codeforces Round 65 (Rated for Div. 2) B. Lost Numbers
链接:https://codeforces.com/contest/1167/problem/B 题意: This is an interactive problem. Remember to flu ...
- OrmLite使用小结(一)
在使用OrmLite过程中,遇到了不少问题.鉴于中文文档比較少,看英文文档又不知道怎样看起.仅仅能遇到问题查找解决方法并整理出来,如有错误,希望能指正! ** 1.模糊条件查询 ** 使用条件查询时. ...
- 【Python】使用cmd模块构造一个带有后台线程的交互命令行界面
最近写一些测试工具,实在懒得搞GUI,然后意识到python有一个自带模块叫cmd,用了用发现简直是救星. 1. 基本用法 cmd模块很容易学到,基本的用法比较简单,继承模块下的Cmd类,添加需要的功 ...
随机推荐
- 2021.05.05【NOIP提高B组】模拟 总结
T1 给你一棵树,要求增加最少的边权是的从根到每一个叶子的长度相等 不能改变原有的最大长度 这是一个贪心:尽可能往深度小的边增加 先预处理出 \(mx_i\) 表示从 \(i\) 到叶子的最大长度 然 ...
- Spring Cloud入门看这一篇就够了
目录 SpringCloud微服务 架构演进 服务调用方式: Euraka服务注册中心 注册中心 服务提供者(服务注册) 服务消费者(服务发现) 服务续约 失效剔除和自我保护 Consul 特性 Co ...
- 数字图像处理-基于matlab-直方图均匀化,傅立叶变换,图像平滑,图像锐化
直方图均匀化 任务:用MATLAB或VC或Delphi等实现图像直方图均匀化的算法. clc;clear;close all; % 清除工作台 % path(path,'..\pics'); % 设置 ...
- element ui 自定义主题失败(primordials is not defined)
卸载: 1.卸载cnpm npm uninstall cnpm -g 2.卸载vue-cli npm uninstall @vue/cli -g 3.卸载nodejs和删除文件 C:\Program ...
- 520到了,作为一个python程序员,必须整点肤白貌美的爬虫代码给你们~
马上520就快到啦~ 整点好看的给你们看下~ 直接开搞~ 代码流程 模拟浏览器向服务器发送一个http请求,网站接收到请求后返回数据.在写爬虫代码的时候一定先要去模拟浏览器访问,因为现在的网站当接收到 ...
- HMS Core音频编辑服务3D音频技术,助力打造沉浸式听觉盛宴
2022年6月28日,HDD·HMS Core.Sparkle影音娱乐沙龙在线上与开发者们见面.HMS Core音频编辑服务(Audio Editor Kit)专家为大家详细分享了基于分离的3D音乐创 ...
- Codeforces Round #790 (Div. 4) A-H
Codeforces Round #790 (Div. 4) A-H A 题目 https://codeforces.com/contest/1676/problem/A 题解 思路 知识点:模拟. ...
- NuGetTools:批量上传、删除和显示NuGet包
快照 前言 NuGet是.NET开发必不可少的包管理工具,在日常更新版本过程中,可能需要批量发布 NuGet 包,也不可避免需要发布一些测试的包,后期想将这些测试或者过期的包删除掉.nuget.org ...
- docker安装Nessus
Nessus家庭版最大只支持扫描16个主机,但利用docker无限使用,当然虚拟机快照也可以. 关于网上其他的破解版,我是没有成功(显示成功了,其实是自慰版),所以才弄得这个镜像 提供两个镜像(不懂d ...
- HTML基础学习笔记(一)
简介 基本形式 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <t ...