【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;
}
相关推荐
澄澈i13 分钟前
设计模式学习[20]---桥接模式
c++·学习·设计模式·桥接模式
西望云天21 分钟前
The 2023 ICPC Asia Shenyang Regional Contest(2023沈阳区域赛CEJK)
数据结构·算法·icpc
我星期八休息43 分钟前
C++异常处理全面解析:从基础到应用
java·开发语言·c++·人工智能·python·架构
zh_xuan1 小时前
LeeCode92. 反转链表II
数据结构·算法·链表·leecode
2401_841495641 小时前
【数据结构】汉诺塔问题
java·数据结构·c++·python·算法·递归·
Q741_1472 小时前
C++ 位运算 高频面试考点 力扣137. 只出现一次的数字 II 题解 每日一题
c++·算法·leetcode·面试·位运算
天特肿瘤电场研究所2 小时前
专业的肿瘤电场疗法厂家
算法
爱编程的鱼2 小时前
Python 与 C++、C 语言的区别及选择指南
c语言·开发语言·c++
奔跑吧邓邓子2 小时前
【C++实战(78)】解锁C++ 大数据处理:从并行到分布式实战
c++·分布式·实战·并发·大数据处理