ABC342 A-G

HUAWEI Programming Contest 2024(AtCoder Beginner Contest 342) - AtCoder

被薄纱的一场

A - Yay!

题意:

给出一串仅由两种小写字母构成的字符串,其中一种小写字母仅出现一次,输出那个仅出现一次的小写字母的位置

代码:

STL偷懒了()

char ch[N];
map<char, vector<int>>mp;
void solve()
{scanf("%s", ch + 1);for (int i = 1; ch[i]; ++i)mp[ch[i]].push_back(i);auto it = mp.begin();if (it->second.size() == 1){printf("%d\n", it->second.back());return;}it = mp.end(); --it;printf("%d\n", it->second.back());return;
}

B - Which is ahead?

题意:

N个人排队,排在第i个位置的人的编号是Pi,给出Q组询问,每组询问输出编号分别为 x 和 y 的人谁在前面

题解:

存下每个人的位置然后查询时直接比较即可

map<int, int>mp;//其实可以直接用数组
void solve()
{int n;scanf("%d", &n);for (int i = 1, x; i <= n; ++i){scanf("%d", &x);mp[x] = i;}int q;scanf("%d", &q);while (q--){int a, b;scanf("%d%d", &a, &b);if (mp[a] < mp[b])printf("%d\n", a);elseprintf("%d\n", b);}
}

C - Many Replacement

题意:

给出一串长度为N的由小写字母构成的字符串和Q次操作,每次操作表示将字符串中的所有ci字符变为di字符,输出经过所有操作之后的字符串

题解:

f[26]记录每种字符经过操作之后变为了什么字符,O(26 * N)就能得出最后每种原本的字符最终会变为哪种字符,具体做法见代码

char ch[N];
int f[26];
void solve()
{for (int i = 0; i < 26; ++i)f[i] = i;int n;scanf("%d%s", &n, ch + 1);int q;scanf("%d", &q);while (q--){char a, b;scanf(" %c %c", &a, &b);for (int i = 0; i < 26; ++i){if (f[i] == a - 'a')f[i] = b - 'a';}}for (int i = 1; i <= n; ++i)printf("%c", f[ch[i] - 'a'] + 'a');
}

D - Square Pair

题意:

给出一个长度为N的数组A,求数对(i, j)满足i < j,  Ai*Aj 是平方数的数对数量

题解:

Ai<=2e5,可以用桶来存下所有的数据,并且我们可以枚举所有平方数(0*0, 1*1, ... , 2e5*2e5)。假设我们要求乘积是 x * x 的数对的数量,首先特判一下Ai = Aj = x的情况(具体见代码),其次对于Ai != Aj的情况,我们可以通过求x * x的所有小于x的因数 t,\sum cnt[t]*cnt[x*x/t] 就是Ai != Aj时的数对数量

对于求x * x的因数显然我们不能直接O(sqrt(x*x))求,由于平方数的性质,我们可以先求出x的因数,然后x的因数与x的因数两两相乘就能求出x * x的因数(总体时间复杂度不太好证,反正这种做法跑了600ms)

最后对于Ai * Aj = 0也需要特判一下

const LL N = 2e5 + 10;
LL a[N], cnt[N];
vector<LL>v[N];
void solve()
{for (int i = 1; i < N; ++i)//nlogn预处理1到N-1所有数的因数{for (int j = i; j < N; j += i)v[j].push_back(i);}int n;scanf("%d", &n);for (int i = 1; i <= n; ++i)scanf("%lld", &a[i]), ++cnt[a[i]];LL ans = cnt[0] * (cnt[0] - 1) / 2 + cnt[0] * (n - cnt[0]);//特判乘积为0for (int i = 1; i < N; ++i){ans += cnt[i] * (cnt[i] - 1) / 2;//特判Ai = Ajvector<LL>t;for (int j = 0; j < v[i].size(); ++j)//求x * x的因数{for (int k = j; k < v[i].size() && v[i][j] * v[i][k] < i; ++k)t.push_back(v[i][j] * v[i][k]);}sort(t.begin(), t.end());t.erase(unique(t.begin(), t.end()), t.end());//去重for (auto j : t){LL k = (LL)i * i / j;if (k < N)ans += cnt[j] * cnt[k];}}printf("%lld\n", ans);
}

E - Last Train

题意:

有一座城市中有N个公交站台,共有M种公交线路(li​, di​, ki​, ci​, Ai​, Bi​) 表示从 li 时刻开始,每 di 单位时间会有一辆公交车从 Ai 出发,经过 ci 时间到达 Bi 站台,并且这种线路总计发车ki辆,在发出第ki辆公交车后不再发车(末班车在 li + (ki - 1) * di 时刻发出)

设f(x)是从x站台出发,最终能够到达站台n的最晚出发时间,求f(1), f(2), ... ,f(n - 1),不能到达输出Unreachable

题解:

假设从Bi站台出发,最终能到达站台n的最晚出发时间是 x ,同时我们有一条公交线路(li​, di​, ki​, ci​, Ai​, Bi​),显然我们可以通过Bi的最晚出发时间x,来更新Ai的最晚出发时间

所以我们可以建反边,跑dijkstra,初始化ans[n] = INF(至少要大于1e18+1e9),其他的ans值为负值

struct edge
{LL v, l, d, k, c;
};
LL ans[N];
vector<edge>e[N];
void solve()
{int n, m;scanf("%d%d", &n, &m);for (int i = 1; i <= n; ++i)ans[i] = -1;for (int i = 1; i <= m; ++i){int l, d, k, c, a, b;scanf("%d%d%d%d%d%d", &l, &d, &k, &c, &a, &b);e[b].push_back({ a,l,d,k,c });}ans[n] = 2e18;priority_queue<PLL>q;q.push({ ans[n],n });while (q.size()){LL u = q.top().second, wu = q.top().first; q.pop();if (wu < ans[u])continue;for (auto& it : e[u]){LL v = it.v, l = it.l, d = it.d, k = it.k, c = it.c;LL mxt = wu - c;if (mxt < l)continue;LL step = (mxt - l) / d;step = min(step, k - 1);LL res = l + step * d;//通过u更新的v的最晚出发时间if (res > ans[v]){ans[v] = res;q.push({ res,v });}}}for (int i = 1; i < n; ++i){if (ans[i] > 0)printf("%lld\n", ans[i]);else printf("Unreachable\n");}
}

F - Black Jack

题意:

你与对手玩这样的一个游戏:游戏使用一个D面骰子能等概率得骰出1到D之间的任意整数,并且有两个初始为0的整数 x 和 y。

刚开始由你先开始投掷,你可以投掷骰子任意次,在每次投掷之后你将这次骰出的点数加到x上,并且选择是否继续投掷。

接下来由你的对手开始投掷,若y<l,则他进行一次投掷,并将骰出的点数加到y上,直到y>=l。

在完成所有投掷后,若x>n,判定为你输了;若x>y或y>n,判定为你赢了;其他情况均判定为你输了,求在你进行最优决策的情况下你的胜率。

题解:

显然对方是做不了决策的,对方最终y为每种值的概率都是确定的,设b[i]为y最终为i的概率

而我方可以做出如下决策:在x <= t时选择继续投掷,直到x > t。对每种决策都可以确定最终x为每种值的概率,设a[i]为x最终为i的概率,同时设f为x <= n的概率,最终答案为\sum_{i=1}^{n}(a[i]* \sum_{j=1}^{i-1}b[j])+f*(1- \sum_{j=1}^{n}b[j]),这里可以b[i]数组进行前缀和优化;对于x <= t+1时继续投掷最终的a[i]可以通过x <= t时继续投掷的a[i]求得,转移是a[i] += a[t] / d,(t < i <= min(n, t + d)) , a[t] = 0,f -= a[t] - a[t] / d * (min(n, t + d) - t)这样最终的时间复杂度是O(N^2),显然还不可做。

对于a[i] += a[t] / d,(t < i <= min(n, t + d))的区间赋值操作我们可以通过差分数组优化掉,而对于确定t时的胜率我们是否也能通过O(1)转移到t + 1,设在t时的胜率为ans,s[i]=\sum_{j=1}^{i}b[i],则a[t] = 0操作损失的胜率为ans -= a[t] * s[i - 1],而对于a[i] += a[t] / d,(t < i <= min(n, t + d)) ,增加的胜率为ans+=\sum_{j=t+1}^{min(n, t + d)}(a[t]/d*s[j-1]),提出a[t]/d,对于\sum s[j-1]显然我们也可以前缀和优化掉,这样就完成了O(1)转移,最后处理一下j - 1的边界问题即可,时间复杂度O(N)

double a[N], b[N], dt[N], ad, s[N], ss[N];//dt[]与ad为差分数组与∑dt[]
void solve()
{int n, l, d;scanf("%d%d%d", &n, &l, &d);a[0] = b[0] = 1;for (int i = 0; i < l; ++i){ad += dt[i];b[i] += ad;dt[i + 1] += b[i] / d;if (i + d < n)dt[i + d + 1] -= b[i] / d;b[i] = 0;}for (int i = l; i <= n; ++i)ad += dt[i], b[i] += ad;for (int i = l; i <= n; ++i)s[i] = s[i - 1] + b[i];for (int i = l; i <= n; ++i)ss[i] = ss[i - 1] + s[i];double ans = 0, t = 0, f = 1;memset(dt, 0, sizeof dt);ad = 0;for (int i = 0; i < n; ++i)//当x<=i时继续投掷的决策{ad += dt[i];a[i] += ad;dt[i + 1] += a[i] / d;if (i + d < n)dt[i + d + 1] -= a[i] / d;int r = min(n, i + d);f -= (d - r + i) * a[i] / d;t += (ss[r - 1] - (i ? ss[i - 1] : 0)) * a[i] / d;if (i)t -= a[i] * s[i - 1];ans = max(ans, t + f * (1 - s[n]));}printf("%.10lf", ans);
}

G - Retroactive Range Chmax

题意:

给出一个长度为N的数组A,对该数组进行Q次操作,操作分为三种:

1 l r x:对所有l, r范围内的数与x取最大值 Ai = max(Ai, x), l <= i <= r

2 i:撤销第i步操作(题目保证第i步操作时1操作并且未被撤销过)

3 i:查询Ai的值

题解:

首先我们不直接对A数组进行操作,可以用类似于线段树的结构来存储修改操作,一棵线段树的结构大致是这样:

假设我们要对区间(3, 7)进行赋值,我们仅需在这些节点放入x

同理若对(2, 5)赋值,我们仅需在这些节点放入x

可以证明最多在2*logn个节点放入x

对于撤销修改操作,我们可以用4*N个multiset来作为线段树的节点,在每次1操作时在对应节点放入x,在每次2操作时在对应节点删除x即可

然后在查询操作时查询i上方的所有节点的最大值,并与Ai取max即可(或者直接在线段树的子节点放入他们原本的值也行),为了不re可以在每个节点都提前塞个0进去

因为用到了线段树+multiset时间复杂度大概在O(q*logn*logn),并且还有点常数跑了2s,但题目给了5s时限,还是嘎嘎过的

int a[N], ql[N], qr[N], x[N];
multiset<int>tr[N << 2];
void updata(int pos, int l, int r, int i)
{if (ql[pos] <= l && r <= qr[pos]){tr[i].insert(x[pos]);return;}int mid = l + r >> 1;if (ql[pos] <= mid)updata(pos, l, mid, i << 1);if (qr[pos] > mid)updata(pos, mid + 1, r, i << 1 | 1);
}
void erase(int pos, int l, int r, int i)
{if (ql[pos] <= l && r <= qr[pos]){tr[i].erase(tr[i].find(x[pos]));return;}int mid = l + r >> 1;if (ql[pos] <= mid)erase(pos, l, mid, i << 1);if (qr[pos] > mid)erase(pos, mid + 1, r, i << 1 | 1);
}
int query(int pos, int l, int r, int i)
{if (l == r)return *tr[i].rbegin();int mid = l + r >> 1, res = *tr[i].rbegin();if (pos <= mid)res = max(res, query(pos, l, mid, i << 1));else res = max(res, query(pos, mid + 1, r, i << 1 | 1));return res;
}
void solve()
{int n;scanf("%d", &n);for (int i = 1; i <= n << 2; ++i)tr[i].insert(0);for (int i = 1; i <= n; ++i)scanf("%d", &a[i]);int q;scanf("%d", &q);for (int i = 1; i <= q; ++i){int op, pos;scanf("%d", &op);if (op == 1){scanf("%d%d%d", &ql[i], &qr[i], &x[i]);updata(i, 1, n, 1);}else if (op == 2){scanf("%d", &pos);erase(pos, 1, n, 1);}else{scanf("%d", &pos);printf("%d\n", max(a[pos], query(pos, 1, n, 1)));}}
}

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2024-02-25 Unity 编辑器开发之编辑器拓展7 —— Inspector 窗口拓展

文章目录 1 SerializedObject 和 SerializedProperty2 自定义显示步骤3 数组、List 自定义显示3.1 基础方式3.2 自定义方式 4 自定义属性自定义显示4.1 基础方式4.2 自定义方式 5 字典自定义显示5.1 SerizlizeField5.2 ISerializationCallbackReceiver5.3 代码示例 1 Serialize…

第三节:kafka sarama 遇到Bug?

文章目录 前言一、先上结果二、刨根问底总结 前言 前面两节&#xff0c;我们已经简单应用了sarama的两个类型Client和ClusterAdmin&#xff0c;其中有一个案例是获取集群的ControllerId&#xff0c;但是在后面的测试过程过程中&#xff0c;发现一个问题&#xff0c;返回的Cont…

北航复试知识点总结

2024.2.25 住行 报道+机试+两天面试=4天 面试流程 (每个人大概20min,早一点到考场!) 形式:5位老师(一记录,四提问) 老师 陆峰 办公地址:北京航空航天大学新主楼H1033 电子邮箱: lufeng@buaa.edu.cn 个人主页:http://shi.buaa.edu.cn/lufeng/ 面试礼仪 于无形中…

锂电池SOC估计 | PyTorch实现基于Basisformer模型的锂电池SOC估计

目录 预测效果基本介绍程序设计参考资料 预测效果 基本介绍 PyTorch实现基于Basisformer模型的锂电池SOC估计 锂电池SOC估计&#xff0c;全新【Basisformer】时间序列预测 1.采用自适应监督自监督对比学习方法学习时序特征&#xff1b; 2.通过双向交叉注意力机制计算历史序列和…

《Docker 简易速速上手小册》第9章 Docker 与持续集成(2024 最新版)

文章目录 9.1 持续集成的基本概念9.1.1 重点基础知识9.1.2 重点案例&#xff1a;Python Web 应用的 CI 流程9.1.3 拓展案例 1&#xff1a;Python 数据分析项目的 CI9.1.4 拓展案例 2&#xff1a;Python 微服务的 CI/CD 9.2 Docker 在 CI/CD 中的应用9.2.1 重点基础知识9.2.2 重…

MATLAB练习题:违背直觉的三门问题(非常有趣的一道题目)

​讲解视频&#xff1a;可以在bilibili搜索《MATLAB教程新手入门篇——数学建模清风主讲》。​ MATLAB教程新手入门篇&#xff08;数学建模清风主讲&#xff0c;适合零基础同学观看&#xff09;_哔哩哔哩_bilibili 三门问题&#xff08;Monty Hall problem&#xff09;又称蒙提…

MATLAB环境下基于图像处理的视网膜图像血管分割

预防糖尿病对每个人的健康至关重要&#xff0c;而糖尿病的早期症状在眼底视网膜血管会有所体现&#xff0c;如静脉血管扩张、轻度弯曲等。高血压作为常见疾病&#xff0c;在中国有多达2.45亿的患者。高血压的病情也会在眼底视网膜血管上有所体现&#xff0c;如交叉压迫征等反映…

Yolov8有效涨点:YOLOv8-AM,添加多种注意力模块提高检测精度,含代码,超详细

前言 2023 年&#xff0c;Ultralytics 推出了最新版本的 YOLO 模型。注意力机制是提高模型性能最热门的方法之一。 本次介绍的是YOLOv8-AM&#xff0c;它将注意力机制融入到原始的YOLOv8架构中。具体来说&#xff0c;我们分别采用四个注意力模块&#xff1a;卷积块注意力模块…

深入探究Nginx的使用方法

目录 引言 一、网络状态页 二、Nginx 第三方模块 三、变量 &#xff08;一&#xff09;内置变量 &#xff08;二&#xff09;自定义变量 四、自定义日志 &#xff08;一&#xff09;有关日志的配置信息 &#xff08;二&#xff09;error日志的设置 1.日志的等级 2.自…

Unity(第六部)向量的理解和算法

标量:只有大小的量。185 888 999 &#xff08;类似坐标&#xff09; 向量:既有大小&#xff0c;也有方向。&#xff08;类似以个体为主体的方向&#xff0c;前方一百米&#xff09; 向量的模:向量的大小。&#xff08;类似以个体为主体的方向&#xff0c;前方一百米、只取一百米…

Qt QWidget 简约美观的加载动画 第四季

&#x1f60a; 第四季来啦 &#x1f60a; 效果如下: 只有三个文件,可以直接编译运行的 //main.cpp #include "LoadingAnimWidget.h" #include <QApplication> #include <QVBoxLayout> #include <QGridLayout> int main(int argc, char *argv[]) …

ARM Cortex-X5 传言表现不佳,高功率浪涌和低多核分数影响即将推出的核心设计

ARM 的新 Cortex-X5 设计似乎遇到了问题&#xff0c;有新的传言称&#xff0c;超级核心在提高时钟速度时会经历严重的高功耗&#xff0c;并且当最大功率限制降低时&#xff0c;多核性能会下降。虽然这对高通来说可能不是问题&#xff0c;因为据说其 Snapdragon 8 Gen 4 采用定制…