cf959 E. Mahmoud and Ehab and the xor-MST(找规律,数学)
2021/12/23 6:37:29
本文主要是介绍cf959 E. Mahmoud and Ehab and the xor-MST(找规律,数学),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
题意:
n个顶点的完全图,编号为0~n-1,任意两点间的边权为两个点的编号的异或,求最小生成树的边权总和。(仍是普通加和,不是异或和)
思路:
为讨论方便,把输入的n减一。
先写个prim找规律,发现除了0外,每个点 \(i\) 都向 \(i \oplus lowbit(i)\) 连一条边。总和就是 \(ans=\sum\limits_{i=1}^n lowbit(i)\)。
设 \(f(x)\) 表示 \(lowbit(y)=x\) 的 \(y\) 的个数,则 \(ans=\sum\limits _{x=1}^n xf(x)\) 。注意到 \(x\) 只能取 2 的幂,所以 \(ans=\sum\limits _{i=0}^{\lfloor logn\rfloor}2^if(2^i)\) 。
那么 \(f(x)\) 怎么算呢?找规律:\(f(4)=|\{4,12,20,28,\cdots(不能超过n)\}|\),公差为8。事实上 \(f(x)=\lfloor\frac{n-x}{2x}\rfloor+1\)
ll n, ans = 0; cin >> n; n--; for(ll x = 1; x <= n; x *= 2) ans += x * ((n-x) / (2*x) + 1); cout << ans;
还可以dp,直接嗯找规律:
每个顶点的边:\(1,2,1,4,1,2,1,8,1,2,1,4,\cdots\) ,发现每次把当前数组复制一遍,然后在中间插一个 \(2^i\) 。长度每次乘2加1。即有 \(ans(1)=dp[1]=1\),\(ans(2^{i}-1)=dp[i]=2*dp[i-1]+2^{i-1}\) 。
\(ans(x)=ans(msb(x)) + ans(x\oplus msb(x))\) ,\(msb(x)\) 表示不超过x的最大的2的幂。加号右边递归下去,最终如果 \(n\) 的第 \(i\) 位为1,答案就加上 \(ans(2^i)=ans(2^i-1+1)=ans(2^i-1)+2^i=dp[i]+2^i\)。即第 \(i\) 位的贡献。
ll n, ans = 0; cin >> n; n--; dp[1] = 1; for(int i = 2; i < 40; i++) dp[i] = dp[i-1]*2 + (1ll<<(i-1)); for(int i = 0; i < 40; i++) if((n>>i)&1) ans += dp[i] + (1ll << i); cout << ans;
这篇关于cf959 E. Mahmoud and Ehab and the xor-MST(找规律,数学)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23增量更新怎么做?-icode9专业技术文章分享
- 2024-11-23压缩包加密方案有哪些?-icode9专业技术文章分享
- 2024-11-23用shell怎么写一个开机时自动同步远程仓库的代码?-icode9专业技术文章分享
- 2024-11-23webman可以同步自己的仓库吗?-icode9专业技术文章分享
- 2024-11-23在 Webman 中怎么判断是否有某命令进程正在运行?-icode9专业技术文章分享
- 2024-11-23如何重置new Swiper?-icode9专业技术文章分享
- 2024-11-23oss直传有什么好处?-icode9专业技术文章分享
- 2024-11-23如何将oss直传封装成一个组件在其他页面调用时都可以使用?-icode9专业技术文章分享
- 2024-11-23怎么使用laravel 11在代码里获取路由列表?-icode9专业技术文章分享
- 2024-11-22怎么实现ansible playbook 备份代码中命名包含时间戳功能?-icode9专业技术文章分享