ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

湖南集训 大新闻 社论

2022-08-10 18:30:46  阅读:148  来源: 互联网

标签:社论 加密 ll 湖南 ans oplus now 集训 位为


大新闻

有一个在 \([0,n)\) 内等概率随机选择的整数,记其为 \(x\) . 我们需要在 \([0,n)\) 内找到某一个整数 \(y\),使得 \(x\oplus y\) 达到最大值 .

问题在于,有可能对 \(x\) 进行了加密 . 情报显示,没有被加密的概率为 \(p\) . 我们决定采取这样的策略:如果 \(x\) 没有被加密,那么我们选出使得 \(x\oplus y\) 最大的 \(y\);否则,我们在 \([0,n)\) 内等概率随机选择一个整数作为 \(y\) .

求 \(x\oplus y\) 的期望 .

\(n\le 10^{18}\) .

你们搞的这个题啊,exciting!

显而易见令 \(p_1\) 是加密过的期望,\(p_2\) 是没加密过的期望,则答案为

\[(1-p)\cdot p_1+p\cdot p_2 \]

可以发现,

\[\begin{aligned}p_1&=\dfrac1{n^2}\sum_{i=0}^{n-1}\sum_{j=0}^{n-1}(i\oplus j)\\p_2&=\dfrac1n\sum_{i=0}^{n-1}\max_{j\in[0,n)}(i\oplus j)\end{aligned} \]


\(\bm{p_1}\) 求法

根据期望线性性我们可以按位考虑,于是

\[p_1=\sum_{i=0}^{\log n}2q_i(1-q_i)2^i \]

其中 \(q_i\) 为从 \([0,n)\) 均匀随机选出一个数,其二进制第 \(i\) 位为 \(1\) 的概率 .

算出第 \(i\) 位为 \(1\) 的个数即可得到

\[a_k=\dfrac1n\left(2^k\cdot\left\lfloor\dfrac n{2^{k+1}}\right\rfloor+\max\{n\bmod 2^{k+1}-2^k,0\}\right) \]

这样暴力算就是 \(O(\log n)\) 的了 .


\(\bm{p_2}\) 求法

一个贪心策略:设最优匹配为 \(y\),从高到低按位考虑,如果 \(x\) 这位是 \(1\) 就跳过,不然如果 \(y\) 加上这一位对应的值仍然小于 \(n\) 就加上 . 根据字典序的原理这显然是对的 .

然而我们要求一行的这个玩意,考虑一个类似数位 DP 的东西,我们算一下前 \(i\) 位和 \(n-1\) 的前 \(i\) 位相同的所有 \(x\) 产生的贡献,设 \(x\) 的最优匹配为 \(y\),分讨一下:

  • \(n-1\) 的第 \(i\) 位为 \(0\) . 则 \(x,y\) 的第 \(i\) 位亦为 \(0\),这时对答案没有什么影响 .
  • \(n-1\) 的第 \(i\) 位为 \(1\),则 \(x,y\) 的第 \(i\) 位必然互为反,但是当 \(x\) 的第 \(i\) 位为 \(1\) 时,后面还会有限制 .

发现三种情况中两种可以直接算,所以一次递归规模至少减半,所以这个也是 \(O(\log n)\) 的,于是总复杂度就是 \(O(\log n)\) 了 .

核心代码:

using namespace std;
typedef long long ll;
typedef double db;
typedef pair<int, int> pii;
db p1(ll n)
{
	db ans = 0;
	ll power = 0, _ = n-1;
	while (_){++power; _ >>= 1;}
	for (int i=power; i; i--)
	{
		ll tmp = (n >> i) * (1ll << (i-1)) + min(n - (n >> i << i), 1ll << (i-1));
		ans += (1 - 1. * (n - tmp) / n) * (1ll << (i-1)) * (n - tmp) / n;
	} return ans * 2;
}
db p2(ll n)
{
	if (n == 1) return 0;
	db ans = 0;
	ll v = 1, d, _ = --n;
	while (v <= _) v <<= 1;
	d = v - 1; v >>= 1;
	ans += 1. * d * (n-v+1) + 1. * v * v;
	ll now = v; d >>= 1;
	while (v > 1)
	{
		v >>= 1; d >>= 1;
		if (n & v){ans += 1. * now * v + 1. * (now >> 1) * d; now >>= 1;}
		else ans += 1. * (now >> 1) * v;
	}
	return ans / (n + 1);
}
ll n; db p;
int main()
{
	scanf("%lld%lf", &n, &p);
	printf("%.6f\n", (1-p) * p1(n) + p*p2(n));
	return 0;
}

标签:社论,加密,ll,湖南,ans,oplus,now,集训,位为
来源: https://www.cnblogs.com/CDOI-24374/p/16573516.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有