【CF】Day75——CF (Div. 2) B (数学 + 贪心) + CF 882 (Div. 2) C (01Trie | 区间最大异或和)

B. Astrophysicists

题目:

思路:

贪心数学

我们很容易想到,我们肯定是每个人分配 (g - 1) / 2 个银币最好,这样就能全贪走剩下的了,同时我们也最多只能贪这么多,我们假设给前 n-1 人分配好了这么多个(假设硬币够多),那么最后一个人最好全收下所有硬币,为什么?

如果不收下,那么就会分给别人,那么现在所贪的数量肯定不会优于之前的,最多只能等于,而最后一个人也只能贪 (g-1)/2 个硬币,所以不如全给最后一个看看还能不能贪

特别的,由于硬币数量可能不足,所以我们还需要取min

代码:

cpp 复制代码
#include <iostream>
#include <algorithm>
#include<cstring>
#include<cctype>
#include<string>
#include <set>
#include <vector>
#include <cmath>
#include <queue>
#include <unordered_set>
#include <map>
#include <unordered_map>
#include <stack>
#include <memory>
using namespace std;
#define int long long
#define yes cout << "Yes\n"
#define no cout << "No\n"

void solve()
{
    int n, k, g;
    cin >> n >> k >> g;
    int onetake = (g - 1) / 2;
    int cantake = min(onetake * n,k*g);
    if (cantake == k*g)
    {
        cout << cantake << endl;
        return;
    }
    cantake -= onetake;
    int x = k * g - cantake;
    int r = x % g;
    if (r >= (g+1)/2)
    {
        cantake += -g + r;
    }
    else
    {
        cantake += r;
    }
    cout << cantake << endl;
}

signed main()
{
    cin.tie(0)->sync_with_stdio(false);
    int t = 1;
    cin >> t;
    while (t--)
    {
        solve();
    }
    return 0;
}

C. Vampiric Powers, anyone?

题目:

思路:

思路题,找特性

我们来观察一下题目,题目可以让我们从后往前取一段异或和然后放到最后做一个新的值,那我们来观察一下有什么特征吗?

我们假设取了一段B放在最后,那么如果我下一步取了 A+B+B 这一段,那么最后的值就变成了 A,因为 A ^ B ^ B = A ^ 0 = A,也就是说其实我们的这个步骤是可以转化为取任意一段区间的异或和的

那么现在就变成了区间最大异或和

由于这题的数据量很小,所以我们可以考虑暴力做法

我们可以定义一个后缀异或和sum,那么对于任意一段 [l,r] 区间就可以表示为 sum[r] ^ sum[l - 1]

然后暴力枚举即可,这里可以看看cf官方的代码,还是很好懂的

当然,我们也可以使用 01Trie ,我们观察一下上面式子,其实这不就是选取最大异或对吗?所以直接套 01Trie 也可解决

代码:

cpp 复制代码
#include <iostream>
#include <algorithm>
#include<cstring>
#include<cctype>
#include<string>
#include <set>
#include <vector>
#include <cmath>
#include <queue>
#include <unordered_set>
#include <map>
#include <unordered_map>
#include <stack>
#include <memory>
using namespace std;
#define int long long
#define yes cout << "Yes\n"
#define no cout << "No\n"

void solve()
{
    int n;
    cin >> n;
    vector<int> a(n);
    for (int i = 0; i < n; i++)
    {
        cin >> a[i];
    }
    int max_val = 1LL << 8;
    vector<bool> f(max_val, 0);
    f[0] = 1;
    int mx = 0;
    int sum = 0;
    for (auto& x : a)
    {
        sum ^= x;
        for (int i = 0; i < max_val; i++)
        {
            if (f[i])
                mx = max(mx, sum ^ i);
        }
        f[sum] = 1;
    }
    cout << mx << endl;
}

signed main()
{
    cin.tie(0)->sync_with_stdio(false);
    int t = 1;
    cin >> t;
    while (t--)
    {
        solve();
    }
    return 0;
}
cpp 复制代码
#include <iostream>
#include <algorithm>
#include<cstring>
#include <iomanip>
#include<cctype>
#include<string>
#include <set>
#include <vector>
#include <cmath>
#include <queue>
#include <unordered_set>
#include <map>
#include <unordered_map>
#include <stack>
#include <utility>
#include <array>
#include <tuple>
using namespace std;
#define int long long
#define yes cout << "YES" << endl
#define no cout << "NO" << endl

void solve()
{
    int n; 
    cin >> n;
    vector<vector<int>> ch((n+1) * 9, vector<int>(2, 0));
    int idx = 0;
    vector<int> a(n + 1);
    vector<int> sum(n + 1, 0);
    int ans = 0;
    for (int i = 1; i <= n; i++)
    {
        cin >> a[i];
        sum[i] = sum[i - 1] ^ a[i];
    }
    auto insert = [&](int x) ->void{  
        int p = 0;
    for (int i = 8; i >= 0; i--)
    {
        int j = x >> i & 1;
        if (!ch[p][j])
        {
            ch[p][j] = ++idx;
        }
        p = ch[p][j];
    }};
    auto query = [&](int x) ->int{ 
        int p = 0, res = 0;
    for (int i = 8; i >= 0; i--)
    {
        int j = x >> i & 1;
        if (ch[p][!j])
        {
            res += 1LL << i;
            p = ch[p][!j];
        }
        else
        {
            p = ch[p][j];
        }
    }
    return res;
        };
    insert(0);
    for (int i = 1; i <= n; i++)
    {
        ans = max(ans, query(sum[i]));
        insert(sum[i]);
    }
    cout << ans << endl;
}
signed main()
{
    cin.tie(0)->sync_with_stdio(false);
    int t = 1;
    cin >> t;
    while (t--)
    {
        solve();
    }
    return 0;
}
相关推荐
海的诗篇_几秒前
移除元素-JavaScript【算法学习day.04】
javascript·学习·算法
自动驾驶小卡11 分钟前
A*算法实现原理以及实现步骤(C++)
算法
Unpredictable22213 分钟前
【VINS-Mono算法深度解析:边缘化策略、初始化与关键技术】
c++·笔记·算法·ubuntu·计算机视觉
编程绿豆侠14 分钟前
力扣HOT100之多维动态规划:1143. 最长公共子序列
算法·leetcode·动态规划
珂朵莉MM20 分钟前
2021 RoboCom 世界机器人开发者大赛-高职组(初赛)解题报告 | 珂学家
java·开发语言·人工智能·算法·职场和发展·机器人
PingdiGuo_guo1 小时前
C++智能指针的知识!
开发语言·c++
Chuncheng's blog1 小时前
CentOS 7如何编译安装升级gcc至7.5版本?
linux·运维·c++·centos
fail_to_code1 小时前
递归法的递归函数何时需要返回值
算法
C137的本贾尼1 小时前
(每日一道算法题)二叉树剪枝
算法·机器学习·剪枝
BUG收容所所长3 小时前
栈的奇妙世界:从冰棒到算法的华丽转身
前端·javascript·算法