A

签到。 值得注意的是,log2 是以2为底的对数,log10 是以10为底的对数,所以 log 就是ln 了,直接输出 150 * log(n) 即可。

B

签到,找准除法的细节。

C

n 的最高位是 pos 那么这个数字就是 1 << (pos + 1) - 1 最高位可以用 __lg(n) 来快速求得

void solve()
{
	int n;
	cin >> n;
	cout << (1 << (__lg(n) + 1) - 1);
}

D

注意到区间内包含1的 gcd的结果一定是1 所以想办法把需要的数字单独划分为一个区间,不需要的数字跟1放在一个区间 就行了 怎么是需要的数字呢?譬如,1101 需要的数字就是 1000, 100, 1 其实就是一个 lowbit 有一些数字是无法取得的,具体来说,因为 gcd 中 1是必然出现的, 所以所有偶数都不行;排列中全体数字的或也就是 (1 << (__lg(n) + 1) - 1 所以 m 超过这个数字也不行 具体代码可以参考下方:

void solve()
{
    int n, m;
    cin >> n >> m;
    if (m % 2 == 0 or m >= (1ll << (__lg(n) + 1)))
    {
        cout << -1;
        return;
    }
 
    auto pos = __lg(m);
    auto mm = m;
    vector<int> v;
    int idx = 0;
    while (mm)
    {
        if (mm & 1)
        {
            v.emplace_back(1ll << idx);
        }
        mm >>= 1;
        idx++;
    }
 
    reverse(all(v));
    map<int, int> mp;
    for (auto num : v)
    {
        cout << num << ' ';
        mp[num] = 1;
    }
    for (int i = 1; i <= n; i++)
    {
        if (!mp.count(i))
        {
            cout << i << ' ';
        }
    }
    cout << endl;
    cout << v.size() << endl;
 
    for (int i = 0; i < v.size(); i++)
    {
        cout << i + 1 << ' ';
        if (i + 1 == v.size())
        {
            cout << n;
        }
        else
        {
            cout << i + 1 << endl;
        }
    }
}

E

可以考虑对所给表达式求导,令导数为0,然后对导数二分或者直接求解都可以。 这里着重讲一下三分。 二分法适用于给出单调函数,查找特定值;三分法适用于给出单峰函数,让求极值。 具体来说,我们给出 lmid = l + (r - l) / 3 rmid = r - (r - l) / 3 这就把整个区间划分成了三个部分 这之后 我们比较 的关系 对于求最小值

  • 如果 :最小值在右半部分,舍弃左半部分
  • 如果 :最小值在左半部分,舍弃右半部分

然后不断重复这个过程即可 代码参考:

double f(double k, double e)
{
    return 2 * k + 2 * e / pow(2, k);
}
 
void solve()
{
    int n;
    cin >> n;
 
    double px, py;
    cin >> px >> py;
 
    double ans = 0.0;
    const double eps = 1e-9;
 
    for (int i = 0; i < n - 1; i++)
    {
        double x, y;
        cin >> x >> y;
 
        double e = sqrt(pow(x - px, 2) + pow(y - py, 2));
 
        // 三分法求最小值
        double l = 0.0, r = 100.0;
        while (r - l > eps)
        {
            double lmid = l + (r - l) / 3;
            double rmid = r - (r - l) / 3;
            if (f(lmid, e) > f(rmid, e))
            {
                l = lmid;
            }
            else
            {
                r = rmid;
            }
        }
 
        double k = (l + r) / 2;
        ans += 2 * k + 2 * e / pow(2, k);
        px = x;
        py = y;
    }
 
    cout << ans;
}