当前位置:网站首页>[ACNOI2022]猜数
[ACNOI2022]猜数
2022-07-03 13:25:00 【OneInDark】
题目
题目背景
“阿喏,” O U Y E \sf OUYE OUYE 忽然说,“我们结为兄弟吧!就是那个,作为条件的延伸。因为像我这样的弱者,不报团取暖就很令人生疑……”
D D ( X Y X ) \sf DD(XYX) DD(XYX) 颇吃了一惊。他没有想到事情会进行的这么顺利。
“那好,回家的路上顺便去拜把子吧!”
“只要内卷不止。” O U Y E \sf OUYE OUYE 想。
“只要红石不完。” D D ( X Y X ) \sf DD(XYX) DD(XYX) 想。
—— “便永不分离!” 二人齐声说。
题目描述
交互题。有一个 x ∈ [ 10 , 2 64 − 10 ) x\in[10,\;2^{64}{-}10) x∈[10,264−10) 未知,你来猜。每次可以给出若干区间:
- 若 x x x 在这些区间的并集当中,则交互库有 p = 0.8 p=0.8 p=0.8 的概率返回 1 1 1,有 ( 1 − p ) (1{-}p) (1−p) 概率返回 0 0 0 。
- 否则,交互库必然返回 0 0 0 。
请你用期望最少的次数确定 x x x 。
数据范围与提示
进行 T = 3000 T=3000 T=3000 次测试后,你的平均询问次数不应超过 107 107 107 。
思路
希望你也有 O U Y E \sf OUYE OUYE 一样的慧眼,足以看出关键信息是 每个数成为答案的概率。
我们用 E n t r o p y \rm Entropy Entropy 衡量它,符号为 H H H 。——你不知道信息熵?那你肯定没有看过 3 b 1 b \rm 3b1b 3b1b 教你玩 w o r d l e \rm wordle wordle
突然发现我也不会信息熵,我是小丑。
定义式
H = − ∑ x ∈ U Pr ( x ) log 2 Pr ( x ) H=-\sum_{x\in\Bbb U}\Pr(x)\log_2\Pr(x) H=−x∈U∑Pr(x)log2Pr(x)
其中 U \Bbb U U 是样本空间。下文简记 ω ( x ) = − x log 2 x \omega(x)=-x\log_2 x ω(x)=−xlog2x 。
这个定义非常符合我们的直觉:注意到 ω ( a b ) = b ω ( a ) + a ω ( b ) \omega(ab)=b\omega(a)+a\omega(b) ω(ab)=bω(a)+aω(b),因此有
H = ∑ x ∈ U ω ( Pr [ x ∣ A ] Pr ( A ) ) + ∑ x ∈ U ω ( Pr [ x ∣ ¬ A ] Pr ( ¬ A ) ) = Pr ( A ) H [ A ] + Pr ( ¬ A ) H [ ¬ A ] + ω ( Pr ( A ) ) + ω ( Pr ( ¬ A ) ) \begin{aligned} H&=\sum_{x\in\Bbb U}\omega(\Pr[x\;|\;A]\Pr(A))+\sum_{x\in\Bbb U}\omega(\Pr[x\;|\;\neg A]\Pr(\neg A))\\ &=\Pr(A)H[A]+\Pr(\neg A)H[\neg A]+\omega(\Pr(A))+\omega(\Pr(\neg A)) \end{aligned} H=x∈U∑ω(Pr[x∣A]Pr(A))+x∈U∑ω(Pr[x∣¬A]Pr(¬A))=Pr(A)H[A]+Pr(¬A)H[¬A]+ω(Pr(A))+ω(Pr(¬A))
其中 H [ A ] H[A] H[A] 为 A A A 条件下的熵,即 ∑ x ∈ U ω ( Pr [ x ∣ A ] ) \sum_{x\in\Bbb U}\omega(\Pr[x\;|\;A]) ∑x∈Uω(Pr[x∣A]) 。
也就是说,用 Pr ( A ) \Pr(A) Pr(A) 对应的熵(信息量)知晓 A A A 是否成立,然后往下递归。
考虑询问一个集合 T T T 满足 Pr [ x ∈ T ] = q , H [ x ∈ T ] = h 1 , H [ x ∉ T ] = h 0 \Pr[x\in T]=q,\;H[x\in T]=h_1,\;H[x\notin T]=h_0 Pr[x∈T]=q,H[x∈T]=h1,H[x∈/T]=h0 。询问之后:
- 有 p q pq pq 的概率得到 1 1 1,然后 Pr [ x ∈ T ] = 1 \Pr[x\in T]=1 Pr[x∈T]=1,新的熵 H = h 1 H=h_1 H=h1 。
- 有 ( 1 − p q ) (1-pq) (1−pq) 的概率得到 0 0 0,由贝叶斯公式 Pr [ x ∈ T ∣ 0 ] = Pr [ 0 ∣ x ∈ T ] Pr [ x ∈ T ] Pr [ 0 ] = q − p q 1 − p q \Pr[x\in T\;|\;0]=\frac{\Pr[0\;|\;x\in T]\Pr[x\in T]}{\Pr[0]}=\frac{q-pq}{1-pq} Pr[x∈T∣0]=Pr[0]Pr[0∣x∈T]Pr[x∈T]=1−pqq−pq,新的熵 H = q − p q 1 − p q h 1 + 1 − q 1 − p q h 2 + ω ( q − p q 1 − p q ) + ω ( 1 − q 1 − p q ) H=\frac{q-pq}{1-pq}h_1+\frac{1-q}{1-pq}h_2+\omega({q-pq\over 1-pq})+\omega({1-q\over 1-pq}) H=1−pqq−pqh1+1−pq1−qh2+ω(1−pqq−pq)+ω(1−pq1−q) 。
原本的熵是 q h 1 + ( 1 − q ) h 2 + ω ( q ) + ω ( 1 − q ) qh_1+(1{-}q)h_2+\omega(q)+\omega(1{-}q) qh1+(1−q)h2+ω(q)+ω(1−q) 。因此,期望下得到的信息量是
Δ H = q h 1 + ( 1 − q ) h 2 + ω ( q ) + ω ( 1 − q ) − p q h 1 − ( 1 − p q ) [ q − p q 1 − p q h 1 + 1 − q 1 − p q h 2 + ω ( q − p q 1 − p q ) + ω ( 1 − q 1 − p q ) ] = ω ( q ) + ω ( 1 − q ) − ( 1 − p q ) [ ω ( q − p q 1 − p q ) + ω ( 1 − q 1 − p q ) ] \begin{aligned} \Delta H&=qh_1+(1{-}q)h_2+\omega(q)+\omega(1{-}q)-pqh_1\\ &-(1{-}pq)\left[\frac{q-pq}{1-pq}h_1+\frac{1-q}{1-pq}h_2+\omega\left(\frac{q-pq}{1-pq}\right)+\omega\left(\frac{1-q}{1-pq}\right)\right]\\ &=\omega(q)+\omega(1{-}q)-(1{-}pq)\left[\omega\left(\frac{q-pq}{1-pq}\right)+\omega\left(\frac{1-q}{1-pq}\right)\right] \end{aligned} ΔH=qh1+(1−q)h2+ω(q)+ω(1−q)−pqh1−(1−pq)[1−pqq−pqh1+1−pq1−qh2+ω(1−pqq−pq)+ω(1−pq1−q)]=ω(q)+ω(1−q)−(1−pq)[ω(1−pqq−pq)+ω(1−pq1−q)]
这也是符合我们的直观感受的——内部元素并没有获得区分,因此内部的熵并不会干扰信息量。
利用在线数学工具(考场上建议打表取最优值)可知最优的
q = 5 ( 5 4000 + 3381 5 − 100 5 − 64 ) 2869 q=\frac{5\left(5\sqrt{4000+3381\sqrt{5}}-100\sqrt{5}-64\right)}{2869} q=28695(54000+33815−1005−64)
它约等于
q ≈ 0.4356636377796835808889 q\approx 0.4356636377796835808889 q≈0.4356636377796835808889
取 q = 0.435 q=0.435 q=0.435 计算,期望 Δ H ≈ 0.618 \Delta H\approx 0.618 ΔH≈0.618 。多么美丽的数字。因此期望下经过 64 Δ H ≈ 103.56 \frac{64}{\Delta H}\approx 103.56 ΔH64≈103.56 次询问后可以出解。
代码
- 因为是期望询问次数,不能用尽 107 107 107 次询问就收,而是出解就 r e t u r n \tt return return 。
- 由于数字多达 2 64 2^{64} 264 个,过程中真实答案的 Pr \Pr Pr 可能降到很低,请不要放弃它!
- 时间复杂度不太好算。但可以想到的是:区间数量是比较少的,约为 64 64 64 个。
#include "guess.h"
#include <cstdio>
#include <algorithm> // Almighty XJX yyds!!!
#include <cstring> // oracle: ZXY yydBUS!!!
#include <cctype> // Huge Egg Dog eats me!!!
#include <vector>
#include <utility>
#include <cmath>
using llong = long long;
# define rep(i,a,b) for(int i=(a); i<=(b); ++i)
# define drep(i,a,b) for(int i=(a); i>=(b); --i)
# define rep0(i,a,b) for(int i=(a); i!=(b); ++i)
inline int readint(){
int a = 0, c = getchar(), f = 1;
for(; !isdigit(c); c=getchar()) if(c == '-') f = -f;
for(; isdigit(c); c=getchar()) a = a*10+(c^48);
return a*f;
}
using ullong = unsigned long long;
using PUU = std::pair<ullong,ullong>;
extern bool Query(std::vector<PUU> v);
bool query(std::vector<PUU> v){
for(PUU &rg : v) -- rg.second;
return Query(v); // close range
}
using ldb = long double;
using NODE = std::pair<PUU,ldb>;
bool cmp(const NODE &a, const NODE &b){
return a.second/(a.first.second-a.first.first)
> b.second/(b.first.second-b.first.first);
}
ullong Guess(){
static const ullong MAXX = 18446744073709551606ull;
std::vector<NODE> v; v.resize(1);
v[0] = NODE{
PUU{
10,MAXX},1};
const long double q = 0.435, p = 0.8, notp = 0.2;
while(true){
if(v[0].first.second == v[0].first.first+1
&& int(v.size()) == 1) return v[0].first.first;
std::vector<PUU> ask; ask.clear();
long double nowq = 0;
for(const NODE &rg : v){
if(nowq >= q) break; // enough
if(nowq+rg.second <= q){
nowq += rg.second; // good
ask.push_back(rg.first); continue;
}
ullong len = rg.first.second-rg.first.first;
ullong cnt = ullong(floor((q-nowq)*len/rg.second));
if(nowq == 0 && cnt == 0) cnt = 1;
if(!cnt) continue; // length = 0
nowq += cnt*rg.second/len; ask.push_back(
PUU{
rg.first.first,rg.first.first+cnt});
}
if(query(ask)){
const int lenask = int(ask.size());
for(int i=0,j=0,k=0; true; ++i){
if(j == lenask){
v.resize(k); break; }
if(ask[j] == v[i].first) // covered
v[k] = v[i], v[k++].second /= nowq, ++ j;
else if(ask[j].first == v[i].first.first){
ullong nxt = ask[j].second-ask[j].first;
ullong now = v[i].first.second-v[i].first.first;
v[k++] = NODE{
ask[j++],v[i].second/nowq*nxt/now};
}
}
}
else{
long double wxk = 1-p*nowq;
const int lenask = int(ask.size()), lenv = int(v.size());
for(int i=0,j=0; i!=lenv; ++i){
v[i].second /= wxk;
if(j == lenask) continue;
if(ask[j] == v[i].first)
v[i].second *= notp, ++ j;
else if(ask[j].first == v[i].first.first){
ullong nxt = ask[j].second-ask[j].first;
ullong now = v[i].first.second-v[i].first.first;
v.push_back(NODE{
ask[j],v[i].second*notp*nxt/now});
v[i].first.first = ask[j++].second; // outside
v[i].second = v[i].second*(now-nxt)/now;
}
}
}
if(true){
// will this be slow?
std::sort(v.begin(),v.end(),cmp);
long double tot = 0;
for(const NODE &rg : v) tot += rg.second;
for(NODE &rg : v) rg.second /= tot;
}
}
}
边栏推荐
- 8 Queen question
- Field problems in MySQL
- The shadow of the object at the edge of the untiy world flickers, and the shadow of the object near the far point is normal
- 金属有机骨架(MOFs)抗肿瘤药载体|PCN-223装载甲硝唑|UiO-66包载盐酸环丙沙星([email protected])
- Replace the GPU card number when pytorch loads the historical model, map_ Location settings
- Which securities company has the lowest Commission for opening an account online? I want to open an account. Is it safe for the online account manager to open an account
- Qt学习22 布局管理器(一)
- Summary of common error reporting problems and positioning methods of thrift
- Go 1.16.4: manage third-party libraries with Mod
- MapReduce implements matrix multiplication - implementation code
猜你喜欢
MySQL 数据处理值增删改
TensorBoard可视化处理案例简析
Flutter动态化 | Fair 2.5.0 新版本特性
[技术发展-24]:现有物联网通信技术特点
Solve MySQL 1045 access denied for user 'root' @ 'localhost' (using password: yes)
又一个行业被中国芯片打破空白,难怪美国模拟芯片龙头降价抛售了
GoLand 2021.1.1: configure the multi line display of the tab of the open file
The latest BSC can pay dividends. Any B usdt Shib eth dividend destruction marketing can
SQL Injection (GET/Select)
Flutter dynamic | fair 2.5.0 new version features
随机推荐
Implementation of Muduo accept connection, disconnection and sending data
The shadow of the object at the edge of the untiy world flickers, and the shadow of the object near the far point is normal
Universal dividend source code, supports the dividend of any B on the BSC
Function calling convention
The solution of Chinese font garbled code in keil5
Golang — 命令行工具cobra
Rasp implementation of PHP
Brief analysis of tensorboard visual processing cases
RocksDB LRUCache
从零开始的基于百度大脑EasyData的多人协同数据标注
Halcon combined with C # to detect surface defects -- Halcon routine autobahn
Go language unit test 4: go language uses gomonkey to test functions or methods
Ocean CMS vulnerability - search php
[bw16 application] instructions for firmware burning of Anxin Ke bw16 module and development board update
Use vscode to view hex or UTF-8 codes
Comprehensive case of MySQL data addition, deletion, modification and query
【556. 下一个更大元素 III】
C language standard IO function sorting
记录关于银行回调post请求405 问题
金属有机骨架(MOFs)抗肿瘤药载体|PCN-223装载甲硝唑|UiO-66包载盐酸环丙沙星([email protected])