【问题标题】:Find the number of even parity numbers between two integers求两个整数之间的偶校验数个数
【发布时间】:2021-04-03 13:59:08
【问题描述】:

我想找到两个整数之间的偶校验数。以下是我目前所写的内容:

#include <bits/stdc++.h>
using namespace std;
#define fastio                        \
    ios_base::sync_with_stdio(false); \
    cin.tie(NULL)
#define ll long long int

bool findParity(ll x)
{
    ll y = x ^ (x >> 1);
    y = y ^ (y >> 2);
    y = y ^ (y >> 4);
    y = y ^ (y >> 8);
    y = y ^ (y >> 16);

    if (y & 1)
        return 1;
    return 0;
}

void solve()
{
    ll a,b; cin >> a >> b;
    ll evenparity = 0;
    for(ll i = a; i <= b; ++i){
        if(findParity(i)==0) evenparity++;
    }
    cout << evenparity;
}

signed main()
{
    fastio;
    solve();
    return 0;
}

这很好用。但是,ab 两个整数之间的差异可以高达10^11,这意味着像这样的O(n) 解决方案将不起作用。有没有更有效的方法,即O(1) 解决这个问题?

【问题讨论】:

  • 只是一个想法-感觉应该可以计算,因为位模式是可预测的。可能需要列举一些开始和结束的案例。
  • 是的,如果不可能使用O(1) 方法,那么约束就不会那么高
  • 如果 a 和 b 是偶数,是否也要计算?
  • Yeah, and the constraints wouldn't be so high if an O(1) approach isn't possible - 错误。 O(log(n)) 可以很好地满足约束条件。

标签: c++ algorithm


【解决方案1】:

你只需要一个从 [0-x] 区间计算偶校验数的函数,我们称之为 sumParity,然后简单地返回 sumParity(b)-sumParity(a-1)。 (如果我理解正确,您正在寻找 [a,b] 闭合区间。)

如果从零开始计算奇偶校验,并将数字配对,(0-1)、(2,3)、(4,5),那么这些对中的每一个都恰好有 1 个偶校验和 1 个奇校验。 (这些对仅在最低位上有所不同)。

所以,如果 x 是奇数,则 sumParity(x) = (x+1)/2,否则 x/2 + parity(x)。

(你已经有了 parity(x) 函数)

f(a,b) = sumParity(b)-sumParity(a-1)

它仅适用于正整数,但您也可以轻松地将逻辑扩展到负数。

【讨论】:

  • 感谢您的清晰解释!
【解决方案2】:

每对偶数/奇数整数只包含一个偶校验数。

因此,只需检查 a 和 b 是否为偶校验数并查看它们是否对它们自己的偶/奇对有贡献,并计算中间对。这是 O(1)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-10-30
    • 2014-03-02
    • 1970-01-01
    • 2015-05-31
    • 1970-01-01
    • 2015-11-13
    • 1970-01-01
    相关资源
    最近更新 更多