2021“MINIEYE杯”中国大学生算法设计超级联赛(1) 1001 Mod, Or and Everything

本文解析了一个关于计算整数n除以1到n-1的余数之和问题,利用等差数列性质简化求解,展示了如何通过预处理2的幂次并确定最大指数来得出答案。代码实现中使用了循环和位运算技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目大意

给出 n n n,求 ( n m o d    1 )   o r ( n m o d    2 )   o r ( n m o d    3 )   o r … o r   ( n m o d    ( n − 1 ) )   o r ( n m o d    n ) (n\mod 1)\ or(n\mod2)\ or(n\mod 3)\ or\dots or\ (n\mod (n-1)) \ or(n\mod n) (nmod1) or(nmod2) or(nmod3) oror (nmod(n1)) or(nmodn)

Solution

对于一个 n n n,从 ⌊ n 2 ⌋ + 1 \lfloor\frac{n}{2}\rfloor+1 2n+1 开始,余数就形成一个公差为 1 的等差数列。因此最后的答案肯定是 2 x − 1 2^x-1 2x1

考虑找出 x x x​ 。而 x x x​ 取决于 ⌊ n + 1 2 ⌋ − 1 \lfloor\frac{n+1}{2}\rfloor-1 2n+11​,因为等差数列的首项是它。首项在二进制下的位数就是 x x x​。

因此有不等式: ⌊ n + 1 2 ⌋ − 1 ≥ 2 x − 1 \lfloor\frac{n+1}{2}\rfloor-1\ge2^{x-1} 2n+112x1​,而目的就是求出最大的 x x x​。

预处理出 2 i 2^i 2i,然后找到最大的 x x x 满足上式,期间一直加上 2 x 2^x 2x 即可。

Code

#include<cstdio>
using namespace std;
#define ll long long
#define G getchar()
ll T, n, l, len, ans, pow[50];
inline ll read()
{
    ll an = 0, ch = G;
    for (; ch < 48 || ch > 57 ; ch = G);
    for (; ch > 47 && ch < 58 ; ch = G)
        an = (an << 3) + (an << 1) + ch - 48; 
    return an;
}
int main()
{
    T = read();
    pow[0] = 1;
    for (ll i = 1 ; i <= 40 ; i++)
        pow[i] = pow[i - 1] << 1;
    while (T--)
    {
        n = read();
        l = n / 2 + 1;
        len = n - l;
        ans = 0;
        for (ll i = 0 ; pow[i] <= len ; i++)
            ans += pow[i];
        printf("%lld\n", ans);
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值