2024牛客暑期多校训练营7

news/2024/11/20 12:39:30/文章来源:https://www.cnblogs.com/luckyblock/p/18346303

目录
  • 写在前面
  • J
  • I
  • K
  • D
  • C
  • H
  • 写在最后

写在前面

比赛地址:https://ac.nowcoder.com/acm/contest/81602#question

以下按个人难度向排序。

dztlb 大神回去补办身份证了,于是单刷,打的像史。

呃呃抽象场。

J

签到。

手玩下发现取定点为两端点时,画出的圆一定可以包含取定点为其他任何点的圆。

于是仅需判断给定点与两端点中一方距离是否不大于 \(L\) 即可。

//
/*
By:Luckyblock
*/
#include <bits/stdc++.h>
#define LL long long
const double eps = 1e-9;
//=============================================================
double l, x, y;
//=============================================================
double dis(double x1_, double y1_, double x2_, double y2_) {return sqrt((x1_ - x2_) * (x1_ - x2_) + (y1_ - y2_) * (y1_ - y2_)); 
}
//=============================================================
int main() {//freopen("1.txt", "r", stdin);std::ios::sync_with_stdio(0), std::cin.tie(0);int T; std::cin >> T;while (T --) {std::cin >> l >> x >> y;if (dis(0, 0, x, y) >= l + eps && dis(l, 0, x, y) >= l + eps) {std::cout << "No\n";} else if (dis(0, 0, x, y) <= l + eps) {std::cout << "Yes\n0\n";} else {std::cout << "Yes\n" << l << "\n";}}return 0;
}

I

签到。

显然答案是有单调性的,考虑二分答案检查枚举量 \(n=\operatorname{lim}\) 时是否合法。

发现在满足 \(n\ge m\) 的情况下,每进行一轮增殖操作,没有增殖过的机器人数改变量为 \(n\rightarrow n - (m - k)\),则最大增殖轮数显然为 \(d=\left\lfloor\frac{n - m}{m - k}\right\rfloor + 1\),仅需判断是否有 \(n + k\times d\ge h\) 即可。

注意特判 \(m=k\)

//
/*
By:Luckyblock
*/
#include <bits/stdc++.h>
#define int long long
//=============================================================
int m, k, h;
//=============================================================
bool check(int mid_) {if (mid_ >= h) return true;if (m == k) return mid_ >= m;if (mid_ < m) return false;int d = (mid_ - m) / (m - k) + 1;return (mid_ + d * k) >= h;
}
//=============================================================
signed main() {// freopen("1.txt", "r", stdin);std::ios::sync_with_stdio(0), std::cin.tie(0);int T; std::cin >> T;while (T --) {std::cin >> m >> k >> h;int ans = h, l = 1, r = h;while (l <= r) {int mid = (l + r) / 2ll;if (check(mid)) {ans = std::min(ans, mid);r = mid - 1;} else {l = mid + 1;}}std::cout << ans << "\n";}return 0;
}

K

枚举,DP。

除了恶心人没意思的缝合题呃呃。

手玩下发现有贡献度子序列 \(seq\) 有两种形态:

  • \(|seq| \ge 2\times |T|\),此时 \(seq\) 中与 \(T\) 匹配的前后缀是不相交的。
  • \(|seq| < 2\times |T|\),此时 \(seq\) 中与 \(T\) 匹配的前后缀有相交部分,说明 \(T\) 的重叠部分的后缀是回文的。

对于第一种 \(seq\),显然取出此类子序列的最优选择,是分别从 \(S\) 的首尾开始匹配得到第一个 \(T\) 构成 \(seq\) 中与 \(T\) 匹配的前后缀。记 \(S\) 中匹配位置分别为 \(l, r\),则 \([l + 1, r - 1]\) 中可以任取本质不同的子序列插入到 \(seq\) 的中间,对该区间 DP 计算本质不同子序列数即可。

对于第二种 \(seq\),发现此类 \(seq\) 数至多仅有 \(|T|\) 种,考虑直接枚举重叠的回文后缀部分的长度 \(l\),并检查 \(S\) 中是否有对应子序列出现即可。对于某个重叠的回文后缀部分的长度 \(l\) 发现仅需保证下列条件即有贡献:

  • \(T[m - l + 1:m]\) 是回文的。可以简单地哈希判断。
  • \(S\) 的开头匹配前缀 \(T[1:m - l]\) 的位置为 \(p_1\)\(S\) 的尾部匹配 \(T\) 的位置为 \(p_2\),有 \(p_1 < p_2\) 成立。预处理一下各个匹配位置即可。

上述两种 \(seq\) 数量求和即为答案。总时间复杂度 \(O(n+m)\) 级别。

//
/*
By:Luckyblock
*/
#include <bits/stdc++.h>
#define LL long long
const int kN = 1e6 + 10;
const LL p1 = 998244353;
const LL c1 = 1145141;
const LL p = 1e9 + 7;
//=============================================================
int n, m, next[26], to1[kN][26], to2[kN][26];
std::string s, t, revt;
std::map<int, int> posrevt, post;
LL ans, pow1[kN], ht[kN], hrevt[kN], f[kN];
//=============================================================
LL hash1(LL *h_, int l_, int r_) {return (h_[r_] - pow1[r_ - l_ + 1] * h_[l_ - 1] % p1 + p1) % p1;
}
bool is_palindrome(int l_, int r_) {bool ret = hash1(ht, l_, r_) == hash1(hrevt, m - r_ + 1, m - l_ + 1);return ret;
}
void init() {pow1[0] = 1;for (int i = 1; i <= m; ++ i) {pow1[i] = pow1[i - 1] * c1 % p1;ht[i] = (c1 * ht[i - 1] + t[i]) % p1;hrevt[i] = (c1 * hrevt[i - 1] + revt[i]) % p1;}for (int i = n; i; -- i) {for (int j = 0; j < 26; ++ j) to1[i][j] = next[j];next[s[i] - 'a'] = i;}for (int i = 0; i < 26; ++ i) to1[0][i] = next[i];for (int i = 0; i < 26; ++ i) next[i] = 0;for (int i = 1; i <= n; ++ i) {for (int j = 0; j < 26; ++ j) to2[i][j] = next[j];next[s[i] - 'a'] = i;}for (int i = 0; i < 26; ++ i) to2[n + 1][i] = next[i];
}
void calc(int l_, int r_) {int lst[26] = {0};f[l_ - 1] = 1;for (int i = l_; i <= r_; ++ i) {if (!lst[s[i] - 'a']) {f[i] = 2ll * f[i - 1] % p;} else {f[i] = (2ll * f[i - 1] % p - f[lst[s[i] - 'a'] - 1] + p) % p;}lst[s[i] - 'a'] = i;}ans = (ans + f[r_]) % p;
}
//=============================================================
int main() {// freopen("1.txt", "r", stdin);std::ios::sync_with_stdio(0), std::cin.tie(0);std::cin >> n >> m;std::cin >> s >> t;revt = t;std::reverse(revt.begin(), revt.end()); revt = "$" + revt;s = "$" + s; t = "$" + t;init();// std::cout << t << "\n" << revt << "\n";int now = n + 1, flag = 1;posrevt[0] = n + 1;for (int i = 1; i <= m; ++ i) {if (!to2[now][t[i] - 'a']) {flag = 0;break;}now = to2[now][t[i] - 'a'];posrevt[i] = now;}now = 0;post[0] = 0;for (int i = 1; i <= m; ++ i) {if (!to1[now][t[i] - 'a']) {flag = 0;break;}now = to1[now][t[i] - 'a'];post[i] = now;}if (!flag) {std::cout << 0 << "\n";return 0;}for (int i = 0; i < m; ++ i) {if (is_palindrome(i + 1, m) && posrevt[m] > post[i]) ++ ans;}// std::cout << ans << "\n";calc(post[m] + 1, posrevt[m] - 1);std::cout << ans << "\n";return 0;
}
/*
14 7
caababaababaac
caababacaababa ac
caababa baac
caababa babaac
caababa ababaac16 7
caababacdababaac
caababa11 7
caabababaac
caababa
*/
/*
10 2
abbbbababa
ab
*/

D

线段树,哈希。

如果不是原CF1418G可能还觉得这题好几种做法都挺有意思,然而是没有任何技术含量的改编,这下只能差评了呃呃;看完题解发现自己赛时的做法就是对的只是查询区间查错了呃呃呃呃呃妈的

考虑枚举区间右端点 \(r\),检查有哪些左端点 \(l\) 是合法的。

考虑前缀 \(1\sim r\) 中的所有权值 \(v\),记 \(v\) 最后 \(k+1\) 次出现位置为 \(p_{v, k+1}, p_{v, k}, \cdots, p_{v, 1}\),为了保证区间内要么恰好有 \(k\)\(v\) 要么一个也没有,则显然合法的区间左端点仅可能位于 \((p_{v, k+1}, p_{v, k}] \cup (p_{v, 1}, r]\) 中。所有 \(v\) 的区间 \((p_{v, k+1}, p_{v, k}] \cup (p_{v, 1}, r]\) 取交即为合法左端点的数量。

上述问题显然可以用线段树维护。初始时所有位置均为 0,考虑在枚举 \(r\) 的同时动态维护每种权值的区间 \((p_{v, k+1}, p_{v, k}] \cup (p_{v, 1}, r]\),并将该区间之外的所有位置均+1。查询时仅需查询 \(1\sim i\) 中有多少个 0 即可。赋值后所有位置的权值均在 \([0, n]\) 中,0 一定是最小值,于是仅需线段树维护区间最小值与区间最小值的数量,查询时仅统计区间最小值为 0 的区间的贡献即可。

总时间复杂度 \(O(n\log n)\) 级别。

//
/*
By:Luckyblock
*/
#include <bits/stdc++.h>
#define LL long long
const int kN = 2e5 + 10;
//=============================================================
int n, k, a[kN];
int next[kN], before[kN], pk[kN], pk1[kN];
//=============================================================
namespace seg {#define ls (now_<<1)#define rs (now_<<1|1)#define mid ((L_+R_)>>1)const int kNode = kN << 2;LL cntmin[kNode], mina[kNode], tag[kNode];void pushup(int now_) {cntmin[now_] = 0;mina[now_] = std::min(mina[ls], mina[rs]);if (mina[now_] == mina[ls]) cntmin[now_] += cntmin[ls];if (mina[now_] == mina[rs]) cntmin[now_] += cntmin[rs];}void pushdown(int now_) {if (!tag[now_]) return ;mina[ls] += tag[now_], mina[rs] += tag[now_];tag[ls] += tag[now_], tag[rs] += tag[now_];tag[now_] = 0;}void build(int now_, int L_, int R_) {tag[now_] = 0;if (L_ == R_) {mina[now_] = 0;cntmin[now_] = 1;return ;}build(ls, L_, mid), build(rs, mid + 1, R_);pushup(now_);}int query(int now_, int L_, int R_, int l_, int r_) {if (l_ <= L_ && R_ <= r_) {if (mina[now_] == 0) return cntmin[now_];return 0;}pushdown(now_);int ret = 0;if (l_ <= mid) ret += query(ls, L_, mid, l_, r_);if (r_ > mid) ret += query(rs, mid + 1, R_, l_, r_);return ret;}void modify(int now_, int L_, int R_, int l_, int r_, int k_) {if (l_ > r_) return ;if (l_ <= L_ && R_ <= r_) {mina[now_] += k_;tag[now_] += k_;return ;}pushdown(now_);if (l_ <= mid) modify(ls, L_, mid, l_, r_, k_);if (r_ > mid) modify(rs, mid + 1, R_, l_, r_, k_);pushup(now_);}
}
void init() {seg::build(1, 1, n);std::map<int, int> lst;for (int i = 0; i <= n + 5; ++ i) {next[i] = before[i] = pk[i] = pk1[i] = 0;}for (int i = n; i; -- i) {if (lst.count(a[i])) next[i] = lst[a[i]], before[lst[a[i]]] = i;lst[a[i]] = i;}for (auto [v, p]: lst) {int p1 = p, flag = 1;for (int i = 1; i < k; ++ i) {if (!next[p1]) {flag = 0;break;}p1 = next[p1];}if (!flag) continue;pk[p1] = p;while (next[p1]) {pk1[next[p1]] = p;p1 = next[p1], p = next[p];pk[p1] = p;}}
}
//=============================================================
int main() {// freopen("1.txt", "r", stdin);std::ios::sync_with_stdio(0), std::cin.tie(0);int T; std::cin >> T;while (T --) {std::cin >> n >> k;for (int i = 1; i <= n; ++ i) std::cin >> a[i];init();LL ans = 0;for (int i = 1; i <= n; ++ i) {if (before[i]) {seg::modify(1, 1, n, 1, pk1[before[i]], -1);seg::modify(1, 1, n, pk[before[i]] + 1, before[i], -1);}seg::modify(1, 1, n, 1, pk1[i], 1);seg::modify(1, 1, n, pk[i] + 1, i, 1);ans += 1ll * seg::query(1, 1, n, 1, i);}std::cout << ans << "\n";}return 0;
}

此外还有一种小清新哈希做法,之后再补,可以看下原CF1418G的题解。

C

构造(?

会并行排序秒了,但是不会。

H

呃呃大模拟,懒得补了。

写在最后

呃呃感觉屁也没学到。

你说的对但是今天是伟大的御阿礼之子第九代稗田阿求同志的三十华诞:

b542dcaaa55c340e088473528532b19a.jpg

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

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

相关文章

读零信任网络:在不可信网络中构建安全系统11用户组的认证和授权

读零信任网络:在不可信网络中构建安全系统11用户组的认证和授权1. 用户组的认证和授权 1.1. 几乎在每个系统中都有一小部分操作需要被密切关注1.1.1. 每个应用对这部分操作的风险容忍度各有不同,且没有任何下限1.1.2. 一部分风险是由用户个人的可信度决定的1.1.2.1. 单个用户…

软件测试设计1探索性测试

1 探索性测试 本章将介绍探索性测试:手动试用新功能,快速获得有关其行为的反馈。我们将详细介绍探索性测试,考虑它的优缺点,以及何时应在项目中执行探索性测试。 我们将了解开始探索性测试所需的先决条件以及应采取的方法。这种测试可以是完整测试计划的一个缩影,它从客户…

Kubernetes高级部署组件 Argo Rollout

Argo介绍 https://argoproj.github.io/ Argo 是一个开源项目,旨在提供一套用于在 Kubernetes 上运行和管理容器化工作负载的工具。 Argo 项目最早在2017年由Applatix公司创立开源,在2018年被美国加利福尼的 Intuit 公司收购并持续维护,并得到了广泛的社区支持。 Argo 项目主要…

n00bzCTF 2024

n00bzCTF 2024n00bzCTF 2024 Crypto Vinegar 题目:Encrypted flag: nmivrxbiaatjvvbcjsf Key: secretkeyexp: 维吉尼亚密码 ​​ flag:n00bz{vigenerecipherisfun} RSA 题目:e = 3 n = 1351123252887151367278321777355120706250832196704807178418175833438514454543565797…

两个coca略有不同词频文件 比较

coca20000xlsxFuzhi.a应该也是这样弄的.txt COCA60000.txt确实有一些词顺序不同,不知道为什么。。。

【第2期】2024 搜索客 Meetup | Elasticsearch 的代码结构和写入查询流程的解读

本次活动由 搜索客社区、极限科技(INFINI Labs)联合举办,活动主题将深入探讨 Elasticsearch 的两个核心方面:代码结构以及写入和查询的关键流程。本次活动将为 Elasticsearch 初学者和有经验的用户提供宝贵的见解,欢迎大家报名参加、交流学习。 活动主题:Elasticsearch 的…

【第2期】2024 搜索客 Meetup | Elasticsearch 的代码结构和写入查询流程的解读.md

本次活动由 搜索客社区、极限科技(INFINI Labs)联合举办,活动主题将深入探讨 Elasticsearch 的两个核心方面:代码结构以及写入和查询的关键流程。本次活动将为 Elasticsearch 初学者和有经验的用户提供宝贵的见解,欢迎大家报名参加、交流学习。 活动主题:Elasticsearch 的…

使用黑群晖webdav服务同步obsidian笔记

前言 本文使用的黑群晖套件 webdav server进行黑群晖配置,接着使用obsidian插件将笔记同步到黑群晖上 使用的黑群晖已经经过内网穿透。 配置黑群晖 配置 webdav 并创建共享文件夹 首先下载套件,在套件中心搜索webdav server ,下载安装并打开进行配置此处已经安装好了,打开,…

文件的读写

1.判断文件夹是否存在 2.文件的数据写入 3.文件内容的读取 4.文件的复制,移动,删除 5.log日志的记录 6.三种序列化器:

Apache Answer Plugin 开发笔记

0x00 引言 在前两天的 Apache CommunityOverCode Asia 2024 大会上认识到了一个很有意思的项目:Apache Answer。这是一个 Apache 开源问答社区系统,可以帮助开发者在社区中快速找到答案。尝试为这个项目做一些贡献,整理一下开发笔记。 领取的任务: incubator-answer-plugins…

2024 暑假集训笔记

Day 1搜索 DFS: 基本思路:边界设置(if(...) return ;) 检查(for(....)) 标记结果(a[...]=...) 递归搜索(dfs(...)) 回溯例题: N皇后问题 [POJ 1321] 棋盘问题 [POJ 1011] Sticks BFS 略分治 基本思路将处理区间二分为两个区间(merge(l,mid) merge(mid+1,r)) 边界(if(l==r) r…

macbook开机登录时输入正确的密码却提示密码错误

背景 Macbook正常的账户登录,提示密码错误,但是我输入的密码确认了几次都是完全正确的,就是死活登不上去一直显示密码错误,一搜索原来是操作系统BUG,有对应解决方案。 原因 系统macOS Monterey 12.0.1设计的原因,导致有某些时刻可能忘记你的开机密码,导致你输入正确的密…