阿里云笔试 - 研发 0316 题解

T1

的方案数,

  • 考虑从高到低按位填数
  • 考虑
    • 对于 ,当且仅当 奇数且这一位全填 ,方案数即为
    • 对于 ,当且仅当这一位不全为 的个数为偶数,方案数
    • 所以 的方案数为
  • 考虑 ,当且仅当二进制高位相等,且第 ,即 偶数且全填 ,低位可以任意填,方案数为 ,故总方案数为
  • 综上所述
    • 为奇数时答案为
    • 为偶数时答案为
  • 时间复杂度 ,不过题目放 的做法过。
#include <bits/stdc++.h>
using namespace std;
const int P = 1e9 + 7;
using ll = int64_t;
int n, k;
int fpow(ll a, ll b, ll x = 1) {
    b %= P - 1;
    for (; b; b >>= 1, a = a * a % P)
        if (b & 1)
            x = x * a % P;
    return x;
}
int main() {
    scanf("%d%d", &n, &k);
    int q = fpow(2, n - 1) + (n & 1 ? 1 : -1), qk = fpow(q, k), ans = qk;
    if (n % 2 == 0) {
        int pn = fpow(2, n);
        ans = (ans + fpow(q - pn + P, P - 2, qk - fpow(pn, k) + P)) % P;
    }
    printf("%d\n", ans);
}

T2

最大化 ,将序列 分为不超过 个非空段, 表示 属于第几段(从 开始),

  • 化简式子

  • 所以答案就是 ,求出前缀和排序或者用堆维护即可。

#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
using ll = int64_t;
int n, k;
int main() {
    scanf("%d%d", &n, &k);
    vector<int> a(n), b(n), s(n);
    string str(n, 0);
    for (auto &x : a) scanf("%d", &x);
    scanf("%s", str.data());
    ll ans1 = 0, ans2 = 0, sn = 0, sum_s = 0;
    priority_queue<int> q;
    for (int i = 0; i < n; ++i) {
        int val = str[i] == '1' ? 1 : -1;
        ans1 += a[i] * val;
        s[i] = (i ? s[i - 1] : 0) + val;
    }
    ans2 = sn = s[n - 1];
    nth_element(s.begin(), s.begin() + k, s.end());
    sort(s.begin(), s.begin() + k);
    for (int i = 0; i < k; ++i) {
        sum_s += s[i];
        ans2 = max(ans2, i * sn - sum_s);
    }
    printf("%lld\n", ans1 + ans2);
    return 0;
}

T3

定义 ,其余情况为 。求

  • 求前缀和 ,统计 的出现次数,求 即可。注意 要枚举到
#include <bits/stdc++.h>
using namespace std;
const int N = 3e5 + 5, M = 50;
using ll = int64_t;
ll pw[M];
void solve() {
    int n;
    scanf("%d", &n);
    unordered_map<ll, int> cnt = {{0, 1}};
    ll sum = 0, ans = 0;
    for (int i = 0, x; i < n; ++i) {
        scanf("%d", &x), ++cnt[sum += x];
        for (int j = 1; j < M; ++j)
            if (cnt.count(sum - pw[j]))
                ans += (ll)cnt[sum - pw[j]] * j;
    }
    printf("%lld\n", ans);
}
int main() {
    pw[0] = 1;
    for (ll i = 1; i < M; ++i)
        pw[i] = pw[i - 1] << 1;
    int t;
    scanf("%d", &t);
    while (t--) solve();
    return 0;
}
#阿里云笔试##阿里云##笔试##技术岗笔试题求解##牛客创作赏金赛#
全部评论
牛啊大佬
点赞 回复 分享
发布于 03-17 02:38 吉林
哇,你提到了阿里云笔试,听起来你最近在准备一些很重要的考试呢!🤓牛可乐在这里为你加油哦!如果你遇到了什么难题,或者想要讨论某个题目的解法,我这个小助手也许能帮到你一点点呢!悄悄告诉你,点击我的头像,我们可以私信聊,这样讨论起来更方便哦!💌🐮🌟
点赞 回复 分享
发布于 03-16 19:01 AI生成

相关推荐

评论
7
11
分享

创作者周榜

更多
牛客网
牛客企业服务