【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;
}
相关推荐
??tobenewyorker16 分钟前
力扣打卡第二十一天 中后遍历+中前遍历 构造二叉树
数据结构·c++·算法·leetcode
贾全37 分钟前
第十章:HIL-SERL 真实机器人训练实战
人工智能·深度学习·算法·机器学习·机器人
GIS小天1 小时前
AI+预测3D新模型百十个定位预测+胆码预测+去和尾2025年7月4日第128弹
人工智能·算法·机器学习·彩票
oioihoii1 小时前
C++11 forward_list 从基础到精通:原理、实践与性能优化
c++·性能优化·list
满分观察网友z1 小时前
开发者的“右”眼:一个树问题如何拯救我的UI设计(199. 二叉树的右视图)
算法
m0_687399841 小时前
写一个Ununtu C++ 程序,调用ffmpeg API, 来判断一个数字电影的视频文件mxf 是不是Jpeg2000?
开发语言·c++·ffmpeg
Natsume17101 小时前
嵌入式开发:GPIO、UART、SPI、I2C 驱动开发详解与实战案例
c语言·驱动开发·stm32·嵌入式硬件·mcu·架构·github
shaun20012 小时前
华为c编程规范
c语言
MeshddY2 小时前
(超详细)数据库项目初体验:使用C语言连接数据库完成短地址服务(本地运行版)
c语言·数据库·单片机
森焱森2 小时前
无人机三轴稳定化控制(1)____飞机的稳定控制逻辑
c语言·单片机·算法·无人机