当前位置:网站首页>[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;
}
}
}
边栏推荐
- Go 1.16.4: purpose of go mod tidy
- 【被动收入如何挣个一百万】
- windos 创建cordova 提示 因为在此系统上禁止运行脚本
- Go language web development series 26: Gin framework: demonstrates the execution sequence of code when there are multiple middleware
- NFT新的契机,多媒体NFT聚合平台OKALEIDO即将上线
- Replace the GPU card number when pytorch loads the historical model, map_ Location settings
- Dlopen() implements dynamic loading of third-party libraries
- 静态链表(数组的下标代替指针)
- Installation impression notes
- Qt学习22 布局管理器(一)
猜你喜欢
Screenshot of the operation steps of upload labs level 4-level 9
Conversion function and explicit
Unity embeddedbrowser browser plug-in event communication
金属有机骨架MOFs装载非甾体类抗炎药物|ZIF-8包裹普鲁士蓝负载槲皮素(制备方法)
GoLand 2021.1: rename the go project
[redis] cache warm-up, cache avalanche and cache breakdown
When updating mysql, the condition is a query
Using registered classes to realize specific type matching function template
JVM family - overview, program counter day1-1
PhpMyAdmin stage file contains analysis traceability
随机推荐
Ocean CMS vulnerability - search php
Qt学习20 Qt 中的标准对话框(中)
JVM family - overview, program counter day1-1
Go language unit test 5: go language uses go sqlmock and Gorm to do database query mock
Multi person collaborative data annotation based on Baidu brain easydata from scratch
There is nothing new under the sun. Can the meta universe go higher?
Flutter动态化 | Fair 2.5.0 新版本特性
使用vscode查看Hex或UTF-8编码
从零开始的基于百度大脑EasyData的多人协同数据标注
Record 405 questions about bank callback post request
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
项目协作的进度如何推进| 社区征文
Open PHP error prompt under Ubuntu 14.04
Golang — template
Unity render streaming communicates with unity through JS
实现CNN图像的识别和训练通过tensorflow框架对cifar10数据集等方法的处理
Software testing is so hard to find, only outsourcing offers, should I go?
Failure of vector insertion element iterator in STL
Go language web development series 26: Gin framework: demonstrates the execution sequence of code when there are multiple middleware
[redis] cache warm-up, cache avalanche and cache breakdown