USACO 2024年2月铜组 MILK EXCHANGE(思维 倍增)

第二题:MILK EXCHANGE

标签:思维、倍增
题意:给定 N N N个数围成环。第 i i i个右边是第 i + 1 i+1 i+1,左边是第 i − 1 i-1 i1。特殊的是第 1 1 1个数 左边是第 N N N个数,第 N N N个数右边是第 1 1 1个数。初始 第 i i i个数为 a i a_i ai。给定一个字符串 s 1 , s 2 , . . . s n s_1,s_2,...s_n s1,s2,...sn,对于第 i i i个字符 s i s_i si要么为 L L L,要么为 R R R。对于 s i = L s_i=L si=L的情况下, a i a_i ai每分钟传递 1 1 1的值给左边;对于 s i = R s_i=R si=R的情况下, a i a_i ai每分钟传递 1 1 1的值给右边。传递都是同时进行的。
传递的过程如果如果值超过了 初始的 a i a_i ai将会溢出,求经过 M M M分钟之后 这些所有数值之和为多少。
1 ≤ N ≤ 2 ∗ 1 0 5 , 1 ≤ M , a i ≤ 1 0 9 1 ≤ N ≤ 2 * 10^5,1 ≤ M,a_i ≤ 10^9 1N21051Mai109
题解:数据很大,模拟每一分钟肯定不现实。我们先观察下一个例子

4 1
RRLL
1 1 1 1

初始 a i a_i ai都是 1 1 1,求第 1 1 1分钟之后 数值之和。
1 1 1分钟的时候, 1 1 1 2 2 2流, 2 2 2 3 3 3流; 4 4 4 3 3 3流, 3 3 3 2 2 2流。我们能发现对于第 2 2 2个和第 3 3 3个来说是没有损失的。但是对于第 1 1 1个和第 4 4 4个来说损失了 1 1 1

推一推能看出来,对于 R R R R L L L L L L RRRRLLLLLL RRRRLLLLLL的,左边连续 R R R和右边连续 L L L都是流向中间 R L RL RL的地方,然后分别溢出的。那溢出多少呢?是不是和时间 M M M相关。那我们其实就去把所有的 R L RL RL找到,然后往左和往右,两边连续的 R R R L L L分别溢出 M M M减去,再求下和即可。注意特判一下全 L L L和全 R R R的情况。
代码

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
const ll N = 2e5 + 10;
string s;
ll cntl = 0, cntr = 0;
ll a[N], n, m, ans = 0, sum = 0;

int main() {
    cin >> n >> m;
    cin >> s;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
        sum += a[i];
        if (s[i - 1] == 'L') cntl++;
        else cntr++;
        a[i + n] = a[i + 2*n] = a[i]; // 倍增
    }

    if (cntl == n || cntr == n) {
        cout << sum << endl;
        return 0;
    }

    s = "@" + s + s + s; // 环 倍增处理
    for (int i = 1; i <= n; i++) {
        if (s[i] == 'R' && s[i + 1] == 'L') {
            ll l = i + n, r = i + 1 + n;
            ll suml = 0, sumr = 0;
            while (l > 1 && s[l - 1] == 'R') {
                l--;
                suml += a[l];
            }
            while (r < 3 * n && s[r + 1] == 'L') {
                r++;
                sumr += a[r];
            }
            // m轮之后 左边连续L剩余的 + 右边连续R剩余的
            ll leave = max(suml - m, 0ll) + max(sumr - m, 0ll);
            ans += a[i] + a[i + 1] + leave; // i和i+1位置牛奶量不变保留
        }
    }
    cout << ans << endl;
    return 0;
}

### 关于202412月USACO比赛题目解答 #### 问题背景与概述 针对202412月USACO的比赛,具体题目细节尚未公布。然而,基于以往的经验和模式,可以推测该次竞赛可能涉及的基础算法概念以及解决问题的方法。 #### 使用双数存储信息 当遇到需要多次访问同一元素的情况时,采用两个独立的数分别记录这些元素的信息是一种有效策略[^1]。这种方法特别适用于那些具有重复操作特性的场景,能够简化逻辑并提高效率。 #### 清零机制的应用 对于某些特定条件下使用的临时变量或辅助结构(比如计数器`num`),适时地将其重置为初始状态是非常重要的。这有助于防止前一次计算残留影响后续的结果准确性。 #### 时间复杂度考量 考虑到实际应用场景中的数据规模较小,即使实现较为复杂的$O(n^2)$甚至更高阶的时间复杂度算法也是可行的选择。这是因为小量级的数据集使得高时间复杂度带来的性能损耗变得微不足道。 #### 枚举法解决交互型游戏类问题 面对像“Why Did the Cow Cross the Road II”这样的互动式博弈论问题,可以通过枚举所有可能性来进行模拟推演。例如,在两轮游戏中根据不同角色的行为合来预测最终得分情况,并据此得出最优解路径[^2]。 #### 动态规划求解资源分配优化模型 以“最小化草地数量”的挑战为例,通过设定动态转移方程,逐步构建起从局部到全局的最佳解决方案框架。这里的关键在于合理定义状态表示方法及其之间的转换关系,从而确保找到满足约束条件下的最优点[^3]。 #### 特殊规则下胜负判定逻辑设计 在类似于“贝茜和朋友玩的游戏”这类含有特殊胜利条件的任务里,重点是要理解规则背后的数学原理。利用回文特性作为判断依据之一,配合其他因素综合考虑,进而形成一套完整的决策流程用于确定胜者身份[^4]。 #### 处理大规模输入输出技巧 针对较大规模的数据处理需求,如岛屿面积统计等问题,则需引入诸如离散化技术等高级手段加以应对。通过对原始坐标系内的点位进行适当变换映射成新的有序序列,既减少了内存占用又加快了运算速度[^5]。 ```python def solve_palindrome_game(T, samples): results = [] for sample in samples: stones = list(map(int, str(sample))) while sum(stones) > 0 and is_palindromic(sum(stones)): # Bessie takes palindromic number of stones first taken_by_bessie = find_largest_palindrome_less_than_or_equal_to(sum(stones)) stones -= [taken_by_bessie] if sum(stones) == 0: break # Friend then takes remaining stones which must be non-palindromic now friend_takes_rest() winner = 'B' if sum(stones)==0 else 'E' results.append(winner) return ''.join(results) def is_palindromic(num): num_str = str(abs(num)) reversed_num_str = num_str[::-1] return num_str == reversed_num_str def find_largest_palindrome_less_than_or_equal_to(max_value): for i in range(max_value, 0, -1): if is_palindromic(i): return i def friend_takes_rest(): pass # Example usage with multiple test cases represented by T=3 here. print(solve_palindrome_game(3,[7, 9, 1])) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值