• 华东师范大学 2017 计算机系暑期夏令营机考


    华东师范大学 2017 计算机系暑期夏令营机考

    传送门:https://acm.ecnu.edu.cn/problem/list/?source=2017 计算机系暑期夏令营机考

    中文题不写题面了

    我不知道我第一次打开界面为啥题号是倒着的,于是先看了“送分题”,然后按序号开的题,我竟反而觉得送分题真的送分题

    有两题还没做,先放放

    3307. 送分题

    idea:

    挺裸的莫队

    直接抄的y总板子改了改

    甚至觉得这题比后面的简单

    code:

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    #include <vector>
    
    using namespace std;
    
    typedef long long LL;
    const int N = 500010;
    
    int n, m, len;
    int w[N], cnt[N];
    LL ans[N];
    struct Query
    {
        int id, l, r;
    }q[N];
    vector<int> nums;
    
    int get(int x)
    {
        return x / len;
    }
    
    bool cmp(const Query& a, const Query& b)
    {
        int i = get(a.l), j = get(b.l);
        if (i != j) return i < j;
        return a.r < b.r;
    }
    
    void add(int x, LL& res)
    {
        if(cnt[x] == 2) res--;
        cnt[x] ++ ;
        if(cnt[x] == 2) res ++;
    //    res = max(res, (LL)cnt[x] * nums[x]);
    }
    
    int main()
    {
        scanf("%d%d", &n, &m);
        len = sqrt(n);
        for (int i = 1; i <= n; i ++ ) scanf("%d", &w[i]), nums.push_back(w[i]);
        sort(nums.begin(), nums.end());
        nums.erase(unique(nums.begin(), nums.end()), nums.end());
        for (int i = 1; i <= n; i ++ )
            w[i] = lower_bound(nums.begin(), nums.end(), w[i]) - nums.begin();
    
        for (int i = 0; i < m; i ++ )
        {
            int l, r;
            scanf("%d%d", &l, &r);
            q[i] = {i, l, r};
        }
        sort(q, q + m, cmp);
    
        for (int x = 0; x < m;)
        {
            int y = x;
            while (y < m && get(q[y].l) == get(q[x].l)) y ++ ;
            int right = get(q[x].l) * len + len - 1;
    
            // 暴力求块内的询问
            while (x < y && q[x].r <= right)
            {
                LL res = 0;
                int id = q[x].id, l = q[x].l, r = q[x].r;
                for (int k = l; k <= r; k ++ ) add(w[k], res);
                ans[id] = res;
                for (int k = l; k <= r; k ++ ) {
                    if(cnt[w[k]] == 2) res--;
                    cnt[w[k]] -- ;
                    if(cnt[w[k]] == 2) res++;
                }
                x ++ ;
            }
    
            // 求块外的询问
            LL res = 0;
            int i = right, j = right + 1;
            while (x < y)
            {
                int id = q[x].id, l = q[x].l, r = q[x].r;
                while (i < r) add(w[ ++ i], res);
                LL backup = res;
                while (j > l) add(w[ -- j], res);
                ans[id] = res;
                while (j < right + 1) {
                    cnt[w[j ++ ]] -- ;
                }
                res = backup;
                x ++ ;
            }
            memset(cnt, 0, sizeof cnt);
        }
    
        for (int i = 0; i < m; i ++ ) printf("%lld\n", ans[i]);
        return 0;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103

    3306. 有钱人买钻石

    3305. 十亿分考

    我随机不过去啊可恶

    看到有人随机过了可能是我随的不太好

    待补充

    礼问正解是啥

    3304. 不等式

    idea:

    相当于两种操作,1-对区间+1,2-询问总体最大值

    离线操作然后离散化+差分

    code:

    #include <bits/stdc++.h>
    
    using namespace std;
    
    typedef long long ll;
    const int inf = 0x3f3f3f3f;
    
    const int N = 700;
    
    struct no {
        int op;
        int num;
    };
    
    vector<no> ques;
    vector<int> vec;
    
    ll pre[N];
    
    signed main() {
        ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
    
        int n;
        cin >> n;
        for (int i = 1; i <= n; ++i) {
            string s;
            cin >> s >> s;
            int x;
            cin >> x;
            vec.push_back(x);
            vec.push_back(x - 1);
            vec.push_back(x + 1);
    
            if (s == "<") {
                ques.push_back({1, x});
            } else if (s == "<=") {
                ques.push_back({2, x});
            } else if (s == "=") {
                ques.push_back({3, x});
            } else if (s == ">=") {
                ques.push_back({4, x});
            } else if (s == ">") {
                ques.push_back({5, x});
            }
        }
    
        vec.push_back(-inf), vec.push_back(inf);
        sort(vec.begin(), vec.end());
        vec.erase(unique(vec.begin(), vec.end()), vec.end());
    
        for (auto[op, num] : ques) {
            int x = lower_bound(vec.begin(), vec.end(), num) - vec.begin();
            if (op == 1) { // <
                pre[1]++;
                pre[x]--;
            } else if (op == 2) { // <=
                pre[1]++;
                pre[x + 1]--;
            } else if (op == 3) { // =
                pre[x]++;
                pre[x + 1]--;
            } else if (op == 4) { // >=
                pre[x]++;
    //            pre[vec.size()]--;
            } else if (op == 5) { // >
                pre[x + 1]++;
            }
        }
    
        int ans = -1;
        int sum = 0;
        int siz = vec.size() - 1;
        for (int i = 0; i <= siz; ++i) {
            sum += pre[i];
            ans = max(ans, sum);
        }
    
        cout << ans << endl;
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80

    3303. 1 的个数最多的整数

    idea:

    以l、r表示上下界,考虑0到r之间1个数最多的数时,1个数起码是r二进制位数-1(可以将r二进制1最高位变成0然后后面全赋成1)

    加上下界,从高位到低位遍历,如果上下界从高位到低位开头一段的二进制一样,这段其实可以不考虑

    对于剩下的部分,最坏情况就是将剩余最高位赋值成0,后面全1,特判能不能直接全1

    code:

    #include <bits/stdc++.h>
    
    using namespace std;
    
    typedef long long ll;
    
    
    signed main() {
        ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
    
        ll T;
        cin >> T;
        for (ll ttt = 1; ttt <= T; ++ttt) {
            cout << "Case " << ttt << ": ";
            ll l, r;
            cin >> l >> r;
            ll pos = 0;
            ll res = 0;
            for (ll i = 63; i >= 0; --i) {
                if (((l >> i) & 1ll) + ((r >> i) & 1ll) == 1ll) {
                    pos = i;
                    break;
                } else {
                    res += ((l >> i) & 1ll) * (1ll << i);
                }
            }
            bool flag = 1;
            for (int i = pos - 1; i >= 0; --i) {
                if (((r >> i) & 1ll) == 0) {
                    flag = 0;
                    break;
                }
            }
            if (flag) res += (r & ((1ll << (pos + 1)) - 1));
            else res += (1ll << (pos)) - 1ll;
    //        cerr << pos << " " << (r & ((1ll <<( pos +1 )) - 1));
            cout << res << endl;
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40

    3302. 打印

    idea:

    分奇偶dp

    code:

    #include <bits/stdc++.h>
    
    using namespace std;
    
    typedef long long ll;
    const ll N = 1e7 + 10;
    
    ll dp[N];
    
    signed main() {
        ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
    
        ll n, x, y;
        cin >> n >> x >> y;
    
        memset(dp, 0x3f, sizeof dp);
        dp[0] = 0;
        dp[1] = x;
    
        for (ll i = 2; i <= n; ++i) {
            if (i & 1) {
                dp[i] = min(dp[i], dp[i - 1] + x);
                dp[i] = min(dp[i], dp[i / 2] + y + x);
                dp[i] = min(dp[i], dp[i / 2 + 1] + y + x);
            } else {
                dp[i] = min(dp[i], dp[i - 1] + x);
                dp[i] = min(dp[i], dp[i / 2] + y);
            }
        }
    
        cout << dp[n] << endl;
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
  • 相关阅读:
    推荐大家一个比较好用的接口测试工具
    Ubuntu中使用yum命令出现错误提示:Command ‘yum‘ not found, did you mean:
    就推荐 4 个 yyds 的开源项目
    Blob和ArrayBuffer和File
    Quartz 体系结构
    mmap()
    基于DCT离散余弦变换的自适应水印算法的设计
    ACE综述
    iOS开发:内存管理
    Maven 和 Gradle 官方文档及相关资料的网址集合
  • 原文地址:https://blog.csdn.net/qq_39602052/article/details/125460192