AtCoder Regular Contest 174 A~E

A.A Multiply(贪心)

题意:

给你一个长度为 N N N A = ( A 1 , A 2 , … , A N ) A=(A_1,A_2,\dots,A_N) A=(A1,A2,,AN) 和整数 C C C 的整数序列。
在进行最多一次以下操作后,求 A A A 中元素的最大可能和:

  • 指定整数 l l l r r r ,并将 A l , A l + 1 , … , A r A_l,A_{l+1},\dots,A_r Al,Al+1,,Ar 分别乘以 C C C

分析:

分类讨论:

  • C > 0 C>0 C>0,求出最大子段和,乘上 C C C,再加上原来非最大子段和的部分即可。

  • C ≤ 0 C \le 0 C0,求出最小子段和,乘上 C C C,再加上原来非最小子段和的部分即可。

代码:

#include <bits/stdc++.h>

using namespace std;
typedef long long LL;
const int N = 3e5 + 5;
int a[N];
int n, c;

int main() {
    cin >> n >> c;
    for (int i = 1; i <= n; i++)
        cin >> a[i];
    if (c > 1) {
        LL now = 0, ans = 0, sum = 0;
        for (int i = 1; i <= n; i++) {
            now = max(now, 0LL) + a[i];
            ans = max(ans, now);
            sum += a[i];
        }
        cout << sum + ans * (c - 1) << endl;
    } else {
        LL now = 0, ans = 0, sum = 0;
        for (int i = 1; i <= n; i++) {
            now = min(now, 0LL) + a[i];
            ans = min(ans, now);
            sum += a[i];
        }
        cout << sum + ans * (c - 1) << endl;
    }
    return 0;
}

B.Bought Review(贪心)

题意:

给出 T T T 个测试用例,解决以下问题。

在美食评论网站 E a t C o c o d e r EatCocoder EatCocoder 上,您可以用从 1 1 1 5 5 5 的整数颗星来评论餐馆。

最初,厨师 B B B 管理的餐厅有 A i A_i Ai 条评论, i i i 颗星。 ( 1 ≤ i ≤ 5 ) (1 \le i \le 5) (1i5)

厨师可以向 E a t C o c o d e r EatCocoder EatCocoder 管理部门支付 P i P_i Pi 日元的贿赂,以获得额外的 i i i 星级评论。 ( 1 ≤ i ≤ 5 ) (1 \le i \le 5) (1i5)

通过贿赂增加 k k k 条评论后,总共会有 A 1 + A 2 + A 3 + A 4 + A 5 + k A_1+A_2+A_3+A_4+A_5+k A1+A2+A3+A4+A5+k 条评论。

厨师 B B B 希望这些评论的平均分至少为 3 3 3 星。请确定实现这一目标所需的最低贿赂总额。

分析:

观察发现只有 A 4 , A 5 A_4,A_5 A4,A5对答案有贡献,只需要比较 2 × A 4 2 \times A_4 2×A4 A 5 A_5 A5的大小即可。之后贪心地进行选择,分三种情况: 1 1 1.全选 A 4 A_4 A4 2 2 2.全选 A 5 A_5 A5 3 3 3.选一个 A 4 A_4 A4,其他的选 A 5 A_5 A5

代码:

#include <bits/stdc++.h>

using namespace std;
typedef long long LL;
LL a[6], p[6];

int main() {
    int t;
    cin >> t;
    while (t--) {
        for (int i = 1; i <= 5; i++)
            cin >> a[i];
        for (int i = 1; i <= 5; i++)
            cin >> p[i];
        int res = a[1] + a[1] + a[2] - a[4] - a[5] - a[5];
        if (res <= 0)
            cout << 0 << endl;
        else if (p[4] + p[4] <= p[5])
            cout << p[4] * res << endl;
        else if (p[5] <= p[4])
            cout << (res + 1) / 2 * p[5] << endl;
        else
            cout << res / 2 * p[5] + res % 2 * p[4] << endl;
    }
    return 0;
}

C.Catastrophic Roulette(期望 dp)

题意:

问题陈述

有一个轮盘,它能以相等的概率从 1 , 2 , … , N 1,2,\dots,N 1,2,,N 中产生一个整数。

两个玩家用它玩下面的游戏:

  • 玩家轮流转动轮盘。

    • 如果产生的整数之前没有出现过,则不会发生任何事情。

    • 否则,转动轮盘的玩家要支付 1 1 1 日元的罚款。

  • 当所有 N N N 个整数都至少出现过一次时,游戏立即结束。

请分别求出第一位和第二位玩家在游戏结束前支付的罚款金额的期望值,取模 998244353 998244353 998244353

分析:

f i , g i f_i,g_i fi,gi表示已经抽了 i i i个数,当前是 A l i c e Alice Alice B o b Bob Bob 抽的,期望罚款。
期望 d p dp dp进行倒推处理, f n = g n = 0 f_n=g_n=0 fn=gn=0 p = i n p=\frac{i}{n} p=ni表示抽到已经有的概率。那么有转移方程:
f i = ( 1 − p ) × g i + 1 + p × g i f_i=(1-p) \times g_{i+1} + p \times g_i fi=(1p)×gi+1+p×gi
g i = ( 1 − p ) × f i + 1 + p × ( f i + 1 ) g_i=(1-p) \times f_{i+1} + p \times (f_i+1) gi=(1p)×fi+1+p×(fi+1)
f i f_i fi带入 g i g_i gi,并通过移项得到:
f i = ( 1 − p ) × g i + 1 + p × ( 1 − p ) × f i + 1 + p 2 1 − p 2 f_i = \frac{(1-p) \times g_{i+1}+p \times (1-p) \times f_{i+1} + p^2}{1-p^2} fi=1p2(1p)×gi+1+p×(1p)×fi+1+p2
求得 g i g_i gi带入求 f i f_i fi即可。答案为 f 1 , g 1 f_1,g_1 f1,g1

代码:

#include <bits/stdc++.h>

using namespace std;
typedef long long LL;
const int N = 1e6 + 5;
const int mod = 998244353;
LL f[N], g[N];

LL inv(LL x, LL y = mod - 2) {
    x = (x % mod + mod) % mod;
    LL ans = 1;
    while (y) {
        if (y & 1)
            ans = 1ll * ans * x % mod;
        x = 1ll * x * x % mod;
        y >>= 1;
    }
    return ans;
}

int main() {
    int n;
    cin >> n;
    for (int i = n - 1, p; i; i--)
        p = 1ll * i * inv(n) % mod,
        f[i] = ((g[i + 1] * (1ll - p) + 1ll * f[i + 1] * p % mod * (1ll - p) + 1ll * p * p) % mod *
                inv(1ll - 1ll * p * p) % mod + mod) % mod,
        g[i] = ((f[i + 1] * (1ll - p) + (f[i] + 1ll) * p) % mod + mod) % mod;
    cout << f[1] << ' ' << g[1] << endl;
    return 0;
}

D.Digit vs Square Root (打表)

题意:

T T T 个测试用例解决以下问题。
给定整数 N N N ,求满足以下所有条件的整数 x x x 的个数:

  • 1 ≤ x ≤ N 1 \le x \le N 1xN
  • y = ⌊ x ⌋ y = \lfloor \sqrt{x} \rfloor y=x .将 x x x y y y 用十进制表示(不带前导零), y y y x x x 的前缀。

分析:

通过打表发现,若 x x x满足条件,那么 x x x是以下两种形式之一:

  • x = 10 0 k − 2 × 1 0 k x=100^k-2 \times 10^k x=100k2×10k
  • x ∈ [ 10 0 k − 1 0 k , 10 0 k + 1 0 k ) x \in [100^k-10^k,100^k+10^k) x[100k10k,100k+10k)

枚举 k k k,计算区间交集即可。

代码:

#include <bits/stdc++.h>

using namespace std;
typedef long long LL;
const int mod = 998244353;

int main() {
    int t;
    cin >> t;
    while (t--) {
        LL n;
        cin >> n;
        LL ans = 1;
        for (LL i = 10; i <= 1000000000; i *= 10) {
            LL tmp = i * i;
            if (n >= tmp - i - i)
                ans++;
            if (n >= tmp - i)
                ans += min(tmp + i - 1, n) - tmp + i + 1;
        }
        cout << ans << endl;
    }
    return 0;
}

E.Existence Counting (树状数组)

题意:

给你整数 N N N K K K 。考虑长度为 K K K 的序列 a = ( a 1 , a 2 , … , a K ) a=(a_1,a_2,\dots,a_K) a=(a1,a2,,aK) ,它满足以下所有条件:

  • a i a_i ai 是一个整数,使得 1 ≤ a i ≤ N 1 \le a_i \le N 1aiN .

  • a a a 中的所有元素都不同。

让我们把所有可能的序列 a a a 按词典顺序排列,形成一个 “序列的序列”,称为字典 s s s

给定一个存在于字典 s s s 中的序列 P P P ,针对每个整数 t = 1 , 2 , … , N t=1,2,\dots,N t=1,2,,N 回答下面的问题:

  • 求满足以下所有条件的序列 b b b 的个数(模为 998244353 998244353 998244353 ):

    • 字典 s s s 中存在序列 b b b

    • 整数 t t t 包含在序列 b b b 中。

    • 序列 b b b 在词法上小于或等于序列 P P P

分析:

首先不考虑必须出现某个数 t t t的限制,只计算 P P P之前有多少排列。和计算排列的时候一样,我们从前往后枚举每个位置 i i i,通过树状数组计算这个位置上能填多少个比现在填的数 P i P_i Pi小的数,再乘上后面的填法数,填法数为 ( n − i ) ! ( n − k ) ! \frac{(n-i)!}{(n-k)!} (nk)!(ni)!。那么 P P P之前有 ∑ i = 1 k ( n − i ) ! ( n − k ) ! ( P i − 1 − ∑ i = 1 j [ P j < P i ] ) \sum\limits_{i=1}^{k}\frac{(n-i)!}{(n-k)!}(P_i-1-\sum_{i=1}^{j}[P_j < P_i]) i=1k(nk)!(ni)!(Pi1i=1j[Pj<Pi])个序列。

再考虑 t t t不出现的序列有多少个。实际上就相当于在序列的值域 [ 1 , n ] [1,n] [1,n]中直接去掉了 t t t这个数,那等价于直接把值域当成 [ 1 , n − 1 ] [1,n−1] [1,n1],然后把所有 P i ​ > t P_i​>t Pi>t 1 1 1。这样,在 [ 1 , n − 1 ] [1,n−1] [1,n1]中,修改过的 P P P之前出现的序列,就和不含 t t t的序列对应。用上面的式子计数即可。

其中 P i ​ = t P_i​=t Pi=t的情况需要特殊考虑。由于这个 P i P_i Pi实际上在值域中并不存在,而是一个比 [ 1 , t − 1 ] [1,t−1] [1,t1]大比 [ t + 1 , n ] [t+1,n] [t+1,n]小的神秘数,所以 i i i后面的所有数都不会造成贡献,需要用另一个树状数组维护每个位置 i i i造成的贡献,然后减掉后面不会造成贡献的一段。另外我们统计的是 P P P之前的序列有多少个含 t t t,所求的范围是包含 P P P本身的,所以此时还需要给答案额外加一。

对于 n n n个询问,我们从小到大处理每个询问,一开始每个 P i P_i Pi都有 P i > t P_i>t Pi>t,所以都要减掉 1 1 1。处理询问的时候每次碰到有 P i ​ = t P_i​=t Pi=t就把 1 1 1加回来。体现在答案上就是减去 ( n − i ) ! ( n − k ) ! \frac{(n-i)!}{(n-k)!} (nk)!(ni)!

代码:

#include <bits/stdc++.h>

using namespace std;
const int N = 3e5 + 5;
int n, k;
int p[N], c[N], d[N], q[N];
const int mod = 998244353;
int tmp[N], invf[N];

int binpow(int x, int y) {
    int ans = 1;
    while (y) {
        if (y & 1)
            ans = 1LL * ans * x % mod;
        x = 1LL * x * x % mod;
        y >>= 1;
    }
    return ans;
}

int cal(int x, int y) {
    return 1LL * tmp[x] * invf[x - y] % mod;
}

void add(int x) {
    for (; x <= n; x += (x & -x))
        c[x]++;
}

int query(int x) {
    int ans = 0;
    for (; x; x -= (x & -x))
        ans += c[x];
    return ans;
}

void change(int x, int val) {
    for (; x <= k; x += (x & -x))
        d[x] = (d[x] + val) % mod;
}

int ask(int x) {
    int ans = 0;
    for (; x; x -= (x & -x))
        ans = (ans + d[x]) % mod;
    return ans;
}

int main() {
    cin >> n >> k;
    tmp[0] = 1;
    for (int i = 1; i <= n; i++)
        tmp[i] = 1LL * tmp[i - 1] * i % mod;
    invf[n] = binpow(tmp[n], mod - 2);
    for (int i = n; i >= 1; i--)
        invf[i - 1] = 1LL * invf[i] * i % mod;
    for (int i = 1; i <= k; i++)
        cin >> p[i];
    for (int i = 1; i <= k; i++)
        q[p[i]] = i;
    int tot = 0;
    for (int i = 1; i <= k; i++) {
        tot = (tot + 1LL * (p[i] - 1 - query(p[i] - 1)) * cal(n - i, k - i)) % mod;
        add(p[i]);
    }
    if (n == k) {
        for (int i = 1; i <= n; i++)
            cout << tot + 1 << endl;
        return 0;
    }
    int sub = 0;
    for (int i = 1; i <= n; i++)
        c[i] = 0;
    for (int i = 1; i <= k; i++) {
        sub = (sub + 1LL * (p[i] - 2 - query(p[i] - 1)) * cal(n - 1 - i, k - i)) % mod;
        change(i, 1LL * (p[i] - 2 - query(p[i] - 1)) * cal(n - 1 - i, k - i) % mod);
        add(p[i]);
    }
    for (int i = 1; i <= n; i++) {
        if (q[i])
            sub = (sub + cal(n - 1 - q[i], k - q[i])) % mod;
        int ans = (tot - sub + mod) % mod;
        if (q[i])
            ans = (ans + ask(k) - ask(q[i]) + 1) % mod;
        if (q[i])
            change(q[i], cal(n - 1 - q[i], k - q[i]));
        cout << (ans + mod) % mod << endl;
    }
    return 0;
}

赛后交流

在比赛结束后,会在交流群中给出比赛题解,同学们可以在赛后查看题解进行补题。

群号: 704572101,赛后大家可以一起交流做题思路,分享做题技巧,欢迎大家的加入。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/484702.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

为什么安装了4GB的内存条,却显示只有3.8GB?

朋友们&#xff0c;对于计算机而言&#xff0c;其基本包含三部分。 第一&#xff0c;CPU; 第二&#xff0c;存储器&#xff08;内存、物理内存&#xff09;&#xff1b;第三&#xff0c;输入设备、输出设备。 32位的地址总线&#xff0c;其地址范围就是 CPU 访问内存&#xf…

小车倒立摆系统极点配置,LQR闭环控制

在之前直流电机控制仿真里有讲过状态控制的基本架构&#xff0c;有兴趣的同学可以再回去看看&#xff0c;链接如下好玩的直流电机调速实验、PID、极点配置、LQR、观测器&#xff1b;不讲大道理_lqr控制器观测器-CSDN博客 在专栏的前三篇文章 小车倒立摆物理建模与simulink仿真…

【消息队列开发】 设计网络通信协议

文章目录 &#x1f343;前言&#x1f38d;明确需求&#x1f340;设计应用层协议&#x1f384;定义 Request / Response&#x1f334;定义参数父类与返回值父类&#x1f332;定义其他参数类&#x1f333;定义其他返回类⭕总结 &#x1f343;前言 本次开发任务 设计网络通信协议…

带3090显卡的Linux服务器上部署SDWebui

背景 一直在研究文生图&#xff0c;之前一直是用原始模型和diffuser跑SD模型&#xff0c;近来看到不少比较博主在用 SDWebui&#xff0c;于是想着在Linux服务器上部署体验一下&#xff0c;谁知道并没有想象的那么顺利&#xff0c;还是踩了不少坑。记录一下过程&#xff0c;也许…

基于springboot+vue的高校专业实习管理系统

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、阿里云专家博主、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战&#xff0c;欢迎高校老师\讲师\同行交流合作 ​主要内容&#xff1a;毕业设计(Javaweb项目|小程序|Pyt…

数据结构面试常见问题之串的模式匹配(KMP算法)系列-大师改进实现以及原理

&#x1f600;前言 KMP算法是一种改进的字符串匹配算法&#xff0c;由D.E.Knuth&#xff0c;J.H.Morris和V.R.Pratt提出的&#xff0c;因此人们称它为克努特—莫里斯—普拉特操作&#xff08;简称KMP算法&#xff09;。KMP算法的核心是利用匹配失败后的信息&#xff0c;尽量减少…

CentOS7配置静态ip

CentOS7进入root账户,点击右上角 点击有线设置 点击有线设置,查看目前ip地址,记住,点击ipv4 点击手动,在下面的地址写你自己想要的IP地址,注意只有最后的100可以改,146改成你自己的网段,网关和DNS最后一位都写2就行了 注意DNS一定要写,要不然让他自动找不到,会断网 在这个位置…

云计算安全分析

目录 一、概述 二、《云计算服务安全指南》的云安全风险分析 2.1 客户对数据和业务系统的控制能力减弱 2.2 客户与云服务商之间的责任难以界定 2.3 可能产生司法管辖权问题 2.4 数据所有权保障面临风险 2.5 数据保护更加困难 2.6 数据残留 2.7 容易产生对云服务商的过度…

手撕算法-删除链表的倒数第 N 个结点

描述 思路 快慢指针&#xff0c;快指针先走N步&#xff0c;走不够N步返回空。慢指针和快指针一起走&#xff0c;当快指针到达终点&#xff0c;即快指针为null时&#xff0c;慢指针到达倒数第N个节点。因为要删除倒数第N个&#xff0c;所以要记录之前的节点pre&#xff0c;假设…

JavaScript原型、原型对象、原型链系列详解(二)

(二)、JavaScript原型对象 原型对象 JavaScript 的原型机制是一种非常强大和灵活的面向对象编程概念&#xff0c;它使用一个对象作为另一个对象的模板&#xff0c;从而实现继承。在 JavaScript 中&#xff0c;每个对象都有一个原型对象&#xff0c;它定义了该对象的属性和方法&…

力扣100热题[哈希]:最长连续序列

原题&#xff1a;128. 最长连续序列 题解&#xff1a; 官方题解&#xff1a;. - 力扣&#xff08;LeetCode&#xff09;题解&#xff0c;最长连续序列 &#xff1a;哈希表 官方解题思路是先去重&#xff0c;然后判断模板长度的数值是否存在&#xff0c;存在就刷新&#xff0c…

【4XVR】win11局域网共享3D影片给quest3

准备工作 首先要有一个路由器&#xff0c;使电脑和quest3处于同一个局域网下 一.创建一个离线账户 打开设置选择账户 添加账户 二.共享文件 选择要共享的文件夹&#xff0c;右键打开属性&#xff0c;点击共享 选择刚刚创建的用户&#xff0c;点击共享即可 三.使用quest观影 …

AttributeError: ‘_MSDataLoaderIter‘ object has no attribute ‘_put_indices‘

问题描述 复现代码过程中遇到错误&#xff1a;AttributeError: _MSDataLoaderIter object has no attribute _put_indices 解决方案 出错的原因是代码中使用了不存在的属性"_put_indices"。这个错误可能与你使用的版本不兼容有关。在pytorch1.x版本中&#xff0c;&q…

Unity基础框架

公共模块 单例基类 如果有很多个这样的单例模式对象,创建他们时都要重复的写单例模式代码。那么能不能利用泛型来减少这部分重复的工作量呢。 单例模式基类,最简单的写法 继承MonoBehaviour的单例基类 所以需要做一些改进 获取单例时如果为空,创建一个名字一样的物体,挂…

力扣HOT100 - 283. 移动零

解题思路&#xff1a; 双指针 指针 i 用于寻找不为零的位置 指针 j 用于寻找为零的位置 不为零时&#xff0c;自己与自己交换&#xff0c;i 和 j 同时向下一个位置移动 为零时&#xff0c;nums[ i ]与nums[ j ]交换&#xff0c;使零向后移动 class Solution {public void…

YOLOv8 | 注意力机制 | 添加ResBlock_CBAM注意力机制——论文必备(全网独家)

⭐欢迎大家订阅我的专栏一起学习⭐ 🚀🚀🚀订阅专栏,更新及时查看不迷路🚀🚀🚀 YOLOv5涨点专栏:http://t.csdnimg.cn/96Cv5 YOLOv8涨点专栏:http://t.csdnimg.cn/hmCtL YOLOv7专栏:http://t.csdnimg.cn/lA95R 💡魔改网络、复现论文、优化创新💡

python学习9:python的代码中的数据类型转换

python中数据类型的转换 1.为什么需要转换类型呢&#xff1f; 数据类型之间&#xff0c;在特定的场景下&#xff0c;是可以相互转换的&#xff0c;如字符串转数字&#xff0c;数字转字符串等&#xff1b;数据类型转换&#xff0c;在以后是我们经常使用到的功能&#xff0c;例如…

js工具方法记录

校验数字是否有效的11位手机号 function isValidPhoneNum(value: string) {return /^[1][3,4,5,6,7,8,9][0-9]{9}$/.test(value) }手机号中间4位掩码 function maskPhoneNum(phone: string, space false) {if (!phone) {return }const reg /(\d{3})\d{4}(\d{4})/return pho…

Linux常用命令和基础命令合集---非常推荐

非常好用的Linux通用基础常用命令和高级命令。 下载链接&#xff1a;https://download.csdn.net/download/lishihuijava/89026399
最新文章