托米的划分

链接:https://www.nowcoder.com/acm/contest/156/B
来源:牛客网
 

托米的划分

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld

题目描述

欧洲人托米非常喜欢数字,他经常在空闲时玩下面的游戏
对于一个数字 n, 托米会随性选中一个数 p, (1 < p <=  n), 将 n 拆分成 ,v=n-u,并对 u,v 重复这个过程,直到他有了 n 个 1
1317 为了挑战托米,在每次托米进行划分时,会给托米奖励 u * v 的分数,托米希望你能帮他最大化他的得分。

输入描述:

第一行一个正整数 T下面 T 行每行一个正整数 n

输出描述:

对于每组数据,输出托米的最大得分

示例1

输入

复制

1 5

输出

复制

10

备注:

T≤ 104, n≤ 109

代码:

#include <iostream>

using namespace std;

int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        long long int n;
        cin>>n;
        cout<<((n-1)+1)*(n-1)/2<<endl;
    }
    return 0;
}

 

### 关于托米的位运算 #### 背景介绍 托米的位运算是一个经典的算法竞赛题目,主要涉及 **按位与操作** 和 **2 的幂次特性**。该问题的核心在于通过选取一组数来最大化其按位与结果的最大可能 2 的幂次 \(2^v\)。 以下是关于此问题的一个具体实现及其解释: --- #### 示例代码解析 以下是一个基于 C++ 实现的解决方案[^1],并附有详细的说明: ```cpp #include <iostream> using namespace std; int main() { int n, cnt; int a[100010]; // 存储输入数组 int b[100010]; // 存储符合条件的子集 cin >> n; // 输入数组长度 for (int i = 0; i < n; ++i) cin >> a[i]; // 输入数组元素 // 遍历每一位(从第30位到第0位) for (int i = 30; i >= 0; --i) { cnt = 0; long long temp = (1LL << 31) - 1; // 初始化临时变量为全1 // 对当前位进行筛选 for (int j = 0; j < n; ++j) { if ((a[j] >> i) & 1) { // 如果当前数的第i位为1 temp &= a[j]; // 更新temp为其与其他候选数的按位与结果 b[cnt++] = a[j]; // 将符合条件的数加入集合b } } // 检查是否找到合法解 if (((temp & (-temp)) == (1 << i))) { // 若temp仅保留了第i位为1,则找到了最大化的v break; } } // 输出结果 cout << cnt << endl; // 输出k值 for (int i = 0; i < cnt - 1; ++i) cout << b[i] << " "; cout << b[cnt - 1] << endl; // 输出最后一个数时不加空格 } ``` --- #### 代码逻辑详解 1. **初始化阶段** - 数组 `a` 用于存储原始输入数据。 - 数组 `b` 用于记录最终选定的子集。 - 变量 `n` 表示输入数组的大小。 2. **逐位遍历** - 外层循环从第 30 位(即 \(2^{30}\))开始向下遍历至第 0 位。 - 这是因为较大的位权优先级更高,有助于更快地找到最优解。 3. **筛选过程** - 内层循环逐一检查每个数的某一位是否为 1。 - 使用 `(a[j] >> i) & 1` 提取第 `i` 位的状态。 - 同时更新 `temp`,使其逐步缩小范围直到只剩下一个特定形式的数值。 4. **合法性验证** - 当前位对应的 `temp` 是否只保留了一个单独的比特位置为 1 是判断的关键。 - 此处利用表达式 `(temp & (-temp)) == (1 << i)` 来确认这一点[^2]。 5. **输出结果** - 记录下满足条件的最大子集数量以及具体的成员列表。 --- #### 核心理论依据 - **2 的幂性质**: 在二进制表示中,任何形如 \(2^v\) 的数都只有一个比特位置为 1,其余均为 0。因此可以通过检测某个数与其负数相与的结果是否等于自身来快速判定它是否属于此类特殊形态。 - **贪心策略应用**: 为了使最终得到的按位与结果尽可能接近更高的 2 的幂次,程序采取了一种自高向低试探的方法,在每一步尝试固定住更多的高位信息直至无法继续为止[^3]。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值