CSP-S 40(爆零记)

news/2025/10/27 20:15:11/文章来源:https://www.cnblogs.com/HS-fu3/p/19170043

10.27

赤到了。

第一次爆蛋。

t1

特判没卡掉11个人。

乐死了。

暴力有80pts。

正解:

发现值域很小只有1000,从此入手。

先预处理 1000 以内的素数,发现很少只有168个,空间可开下,这启发我们对于每个素数记录东西。

开vector \(d\) 存每个位置上的数分解质因数后含有的素数下标

限制了 \(i\le j\) ,于是我们倒序处理,用后面的信息更新之前的信息。

数组 \(dd_{i,j}\) 表示当前含有第 \(i\) 个素数的位置所能到达的最小的含有第 \(j\) 个素数的位置。

数组 \(idd_{i,j}\) 表示当前\(i\) 个位置所能到达的最小的含有第 \(j\) 个素数的位置。

两者相互转移即可。

注意一大堆特判。

特别的:因为 \(\gcd(0,x)=x\) ,所以 \(0\) 可做任意两点间的中转点。

记数组 \(spe_i\) 表示由于 \(0\) 的存在,第 \(i\) 位置可到达的最近距离(以后也均可达)。

同时转移即可。

还是注意特判!!!

code

可恶的0与1
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
const int M = 170;
bool flag[N];
int pri[M], cnt;
int n, q;
vector<int> d[N];
int a[N];
int id_d[N][M], dd[M][M], spe[N];inline void xxs()
{for (int i = 2; i <= 1000; ++i){if (!flag[i])pri[++cnt] = i;for (int j = 1; j <= cnt; ++j){if (i * pri[j] > 1000)break;flag[i * pri[j]] = 1;if (i % pri[j] == 0)break;}}
}signed main()
{freopen("gcd.in", "r", stdin);freopen("gcd.out", "w", stdout);ios::sync_with_stdio(0);cin.tie(0);xxs();cin >> n >> q;for (int i = 1; i <= n; ++i){cin >> a[i];for (int j = 1; j <= cnt; ++j){if (a[i] % pri[j] == 0)d[i].emplace_back(j);if (pri[j] > a[i])break;}}memset(id_d, 0x3f, sizeof(id_d));memset(dd, 0x3f, sizeof(dd));memset(spe, 0x3f, sizeof(spe));for (int i = n; i; --i){if (!a[i]){spe[i] = i;continue;}spe[i] = spe[i + 1]; // 0及其之后都合法for (auto j : d[i]){for (int k = 1; k <= cnt; ++k)id_d[i][k] = min(id_d[i][k], dd[j][k]);}for (auto j : d[i])dd[j][j] = i, id_d[i][j] = i;for (auto j : d[i]){for (int k = 1; k <= cnt; ++k)dd[j][k] = min(dd[j][k], id_d[i][k]);}}int x, y;while (q--){cin >> x >> y;if (x == y)puts("Shi");else if (a[x] == 1 || a[y] == 1)puts("Fou");else if (!a[x] && !a[y]){for (int i = x + 1; i < y; ++i)if (a[i] > 1){puts("Shi");goto con;}puts("Fou");}else if (y >= spe[x])puts("Shi");else{for (auto i : d[y]){if (id_d[x][i] <= y){puts("Shi");goto con;}}puts("Fou");}con:;}return 0;
}

t2

构造题。

其实不难,赛时被 t1 恶心到了,看到 t2 脑子根本就是全是模拟。

反正就是爆了。

正解:

容易发现栈的数量至多为 2(两个栈一定可满足要求)。

尝试先判断栈的数量,发现不好弄。

不妨假设只有一个栈,每次以最优策略转移,若最终栈非空则需要两个栈。

一个栈很好做了,不多赘述。

加入另一个栈如何做?

我们可以将第二个栈当成中转站,对于每一个要取出的元素,将该元素上方的所有元素放到第二个栈中,之后取出该元素,再将刚才取出的元素放回。

发现唯一麻烦的就是求操作次数,设当前要拿出的元素的位置是 \(p\) ,次数 显然为 \(p-1-该元素上方的小于该元素值的元素个数\)(因为该元素上方的小于该元素值的元素个数在此之前已经被弹出了)。

这东西就是一个区间查询和单点加,拿个数据结构维护以下就行(线段树,树状数组什么的)。

code

具体细节看代码
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int T, n;
int a[N], b[N];
int stk[N], top, topb, tot;
struct node
{int opt, i, j, cnt;
} ans[N << 2];
int c[N];
vector<int> num[N];#define lowbit(x) (x & (-x))inline void add(int pos, int val)
{for (int i = pos; i <= n; i += lowbit(i))c[i] += val;
}inline int query(int pos)
{int ans = 0;for (int i = pos; i; i -= lowbit(i))ans += c[i];return ans;
}inline void write(int x)
{cout << x << "\n";cout << tot << "\n";for (int i = 1; i <= tot; ++i){if (ans[i].opt == 1)cout << ans[i].opt << ' ' << ans[i].i << ' ' << ans[i].cnt << "\n";if (ans[i].opt == 2)cout << ans[i].opt << ' ' << ans[i].i << "\n";if (ans[i].opt == 3)cout << ans[i].opt << ' ' << ans[i].i << ' ' << ans[i].j << ' ' << ans[i].cnt << "\n";}
}inline void solve()
{cin >> n;for (int i = 1; i <= n; ++i)cin >> a[i], b[i] = a[i];sort(b + 1, b + 1 + n);stk[0] = 0;tot = top = 0;topb = 1;for (int id = n; id; --id){if (a[id] == b[topb]){// cerr << "id=" << id << "\n";ans[++tot] = {1, 1, 114514, 1};ans[++tot] = {2, 1, 114514, 1};++topb;while (top){if (stk[top] != b[topb])break;// cerr << "top=" << top << "\n";ans[++tot] = {2, 1, 114514, 1};--top, ++topb;}}else{ans[++tot] = {1, 1, 114514, 1};stk[++top] = a[id];}}if (!top){write(1);return;}else{vector<int> now;reverse(stk + 1, stk + top + 1);// cerr << "top=" << top << "\n";for (int i = 1; i <= n; ++i)c[i] = 0;for (int i = 1; i <= top; ++i)num[stk[i]].emplace_back(i), now.emplace_back(stk[i]);now.emplace_back(1e9);sort(now.begin(), now.end());for (int i = 1; i < now.size(); ++i)if (now[i - 1] != now[i])for (auto p : num[now[i - 1]]){int dx = p - 1 - query(p - 1);if (dx)ans[++tot] = {3, 1, 2, dx};ans[++tot] = {2, 1, 0, 0};if (dx)ans[++tot] = {3, 2, 1, dx};add(p, 1);// cerr << "i=" << i << "\n";}// cerr << "\n";for (int i = 1; i <= top; ++i)num[stk[i]].clear();write(2);}
}signed main()
{freopen("sort.in", "r", stdin);freopen("sort.out", "w", stdout);ios::sync_with_stdio(0);cin.tie(0);cin >> T;while (T--)solve();return 0;
}

t3

不是你赛场高精???

破防了。

t4

神秘dp。

真不是每个包拆开都成一道题了?

直接看题解吧:

对于每个点,称距离其最近的染色点为配对染色点。

观察到:对于子树 \(u\) 的所有点,其配对染色点至多只有1个在子树外(若有多个可以只留距离 \(u\) 点最近的)。

设计动态规划 \(dp[u][j]\) 代表搞定 \(u\) 子树、且 \(u\)\(j\) 配对的最小花费,记 \(f[i]=\min(dp[i][j])\),答案为 \(f[1]\)

考虑转移,对于 \(dist(i, j)\leq d[i]\) 的状态,考虑 \(u\) 的每个儿子 \(v\)

  • \(v\) 子树的配对集合完全在子树内,贡献为 \(f[v]\)
  • \(v\) 子树的配对集合除了 \(j\) 点都在子树内,贡献为 \(f[v]-c[j]\)
  • \(v\) 子树的配对集合有在子树外、且不是 \(j\) 的其他点 \(j'\),则不是最优解(子树外多余1个)

转移方程为 \(d p[u][j]=c[j]+\sum \min (f[v], dp[v][j]-c[j])\),复杂度 \(O(tn^2)\)

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

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

相关文章

javascript构造对象数组向服务器端传输

javascript构造对象数组向服务器端传输客户端发送数据1 $("#saveEnable").click(function () {2 var selectedRows = $(#userTab).datagrid(getSelections);3 4 var users…

102302136 林伟杰 数据采集与融合作业1

目录作业一实验过程及结果-1 心得体会-1作业二实验过程及结果-2 心得体会-2作业三实验过程及结果-3 心得体会-3作业一: 实验过程及结果-1要想爬取到网站中大学的信息,应当先查看该网站中html的结构,通过搜索框搜索&…

TCP/IP协议概述

TCP/IP分层模型是互联网协议套件的基础,它简化了OSI模型,将网络通信过程划分为四个层次。TCP/IP模型的主要目的是提供一个实际可行的网络通信架构,它是互联网和许多其他网络的基础。TCP /IP,是一组不同层次上的多个…

极值定理

若函数 \(f\) 在 \(x = c\) 处有一个局部最大值或局部最小值,则 \(f\) 在 \(x = c\) 处不可导或者 \(f(c)=0\) 。 比如说 \(f\) 在 \(x = c\) 处是个尖角,那么肯定就不可导。 若可导,不妨令是最大值(最小值类似)则…

10.25 CSP-S 模拟赛

Contest CSP-ST1 你脑子呢? 确定的情况即选比 \(a_i\) 小的,记 \(a_i\) 的排名为 \(rank_i\),则答案为 \(\binom{rank_i - 1}{k - 1}\)。 T2 大力分讨。 无论什么情况都有一个直接走到的选项 \(\operatorname{lcm}(…

【CI130x 离在线】如何运行 curl 脚本

在各种大模型的API文档中,经常会用到 curl 工具,那么——如何运行 curl 脚本呢?在Linux平台 对于复杂的代码,建议创建脚本文件:# 创建脚本文件 nano myscript.sh然后执行以下指令 # 在文件中粘贴代码,然后保存退…

日总结 18

Hive 是基于 Hadoop 生态的大数据仓库工具,通过类 SQL 的 HQL 语法简化大规模结构化 / 半结构化数据的离线批处理,底层依赖 HDFS 存储数据,计算引擎支持 MapReduce、Tez、Spark 等;其架构包含用户接口、元数据存储…

一场比赛

题目难度 颜色 分值入门 红 100普及- 橙 150普及/提高- 黄 250普及+/提高 绿 500提高+/省选- 蓝 1500省选/NOI- 紫 3500

这才是真正的AI NAS!极空间私有云Z2Ultra评测

这才是真正的AI NAS!极空间私有云Z2Ultra评测Posted on 2025-10-27 20:02 lzhdim 阅读(0) 评论(0) 收藏 举报一、前言 在NAS以及私有云领域,可能有些老玩家只知道群晖。但实际上根据天猫及京东销售数据统计,极…

新东方第三节课名言作文

开头段:1引入名言(照抄);2概括名言主题(补充一下);3个人立场(证据)A famous and enlihtening saying goes that"Respect others,and you will be respected."This remark convers a thought-provok…

【性能优化必看】CPU耗时飙高?GC频繁停顿?一文教你快速定位!​

本文分享了Java应用性能问题的排查方法,分为CPU飙升和JVM排查两部分。CPU问题排查需从进程到线程递进分析,使用top、jstack等工具定位高负载线程和代码位置。JVM排查则涉及内存溢出、GC异常等场景,通过jstat、jmap等…

​Fedora 37 安装 libicu-71.1-2.fc37.x86_64.rpm 教程(命令行步骤)​

​Fedora 37 安装 libicu-71.1-2.fc37.x86_64.rpm 教程(命令行步骤)​​一、先确认你的系统 这个包是 ​Fedora 37、64位系统(x86_64)​​ 的,所以:你得是 ​Fedora 37​ 系统电脑是 ​64位​ 的(现在大多数都是…

十月阅读_3

“简单工具的力量” 在本章被诠释得淋漓尽致。作者以 “石头剪刀布” 的极简逻辑,隐喻编程中 “基础思维决定复杂问题解法” 的本质。我曾在一个分布式任务调度项目中,因过度依赖第三方框架的复杂配置而陷入困境;后…

学校协同云盘怎么选?2025年10大热门教育网盘推荐与对比

为满足学校在教学、科研与安全合规上的需求,选择合适的协同云盘至关重要。本文深度对比了坚果云与Zoho两款主流方案。坚果云凭借其专业的无感同步、强大的文件历史版本功能以及金融级的公安部等保三级安全认证,在效率…

从神经信号到驾驶安全:Mentalab无线脑电图系统赋能汽车人因研究与HMI优化 - 指南

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

GPU集群之间的交互

目前,分散在各地的GPU智算集群之间通常没有直接的、实时的相互调用关系来共同训练一个单一的大模型。它们之间的关系更多是独立运作、资源错配或通过更高层级的调度系统进行间接协调,而不是像单个集群内部的GPU那样紧…

Java并发编程基础:从线程管理到高并发应用实践

本篇主要是多线程的基础知识,代码示例较多,有时间的可以逐个分析,具体细节都放在代码注释中了。 1. 理解线程:多任务执行的基石 1.1 什么是线程? 在现代操作系统中,进程是资源分配的基本单位,而线程是CPU调度的最…

基于ECharts 6.0实现实时材料监控看板

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

python爬取京东评论 -

python爬取京东评论使用DrissionPage模块进行爬取,DrissionPage是一个自动化的模块,可以模拟人的操作,进行翻页等操作,比传统爬取更加方便 在使用DrissionPage之前,需要先初始化路径运行下面的代码,需要将rD:\Ch…

CF1267G Game Relics

CF1267G Game Relics有 \(n\) 个物品,你可以进行下面两种操作:花费 \(c_i\) 元购买第 \(i\) 个物品。花费 \(x\) 元抽奖,等概率随机获得一个物品 \(i\)。若你已经拥有第 \(i\) 个物品,则你本次抽奖的花费改为 \(\d…