【2024.09.27】NOIP2024 赛前集训-刷题训练(3)

NOIP2018 提高组 铺设道路

算法一:模拟正常人铺路的过程,每次找区间的最小值,最小值就是本次填的高度,由于出现了若干个0位置,就分裂成若干个子区间去重复上述过程,直到全部变成0。时间复杂度 \(O(nlogn)\), 瓶颈在预处理 st表。

算法二:若 \(a[i - 1] < a[i]\), 则 \(ans += a[i] - a[i - 1], i \in [0,n]\)。 感性理解一下: \(\forall i, a[i] <= a[i - 1]\) 的情况都会被顺便删掉。

所以其实以下两种写法都是对的:

	//写法一
F(i, 2, n + 1) if(a[i] < a[i - 1]) ans += a[i - 1] - a[i];
//写法二
F(i, 1, n) if(a[i] > a[i - 1]) ans += a[i] - a[i - 1];

NOIP2018 提高组 货币系统

结论就是如果货币系统里的一些数可以由其他数表示出来,那么这样的数就可以被删掉。

那么每往新的货币系统里加一个数,就把 能由它的若干倍表示的数 都标记上(值域很小),剪下枝就过了。

#include<bits/stdc++.h>
#define F(i,l,r) for (int i(l); i<=(r); ++i)
#define G(i,r,l) for (int i(r); i>=(l); --i)
using namespace std;
using ll = long long;
const int N = 1e5 + 5,mx = 25000;
int t[N], a[N];
int n, T;
signed main(){
// freopen("money.in","r",stdin);
// freopen("money.out","w",stdout);
ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
cin >> T;
while(T --){
cin >> n;
F(i, 1, n) cin >> a[i];
sort(a + 1, a + n + 1);
if(a[1] == 1){
cout << "1\n";
continue;
}
memset(t, 0, sizeof(t));
t[0] = 1;
int ans = 0;
F(i, 1, n){
if(t[a[i]]) continue;
++ans;
F(j, 0, mx) if(t[j] && !t[j + a[i]]) for(int k = a[i];j + k <= mx; k += a[i]) t[j + k] = 1;
}cout << ans << '\n';
}
return fflush(0),0;
}

NOIP2018 提高组 赛道修建

\(m = 1\):自底向上dp就行。

\(a_i = 1\):菊花图,做法显然。

\(b_i = a_i + 1\):链,在序列上二分即可。

分支不超过3:根最多三叉,别的点最多二叉,观察一下发现一个儿子的贡献要么向另一个儿子拐,要么穿过父节点继续向上,由此想到自底向上贪心。(提示正解)

综上有80pts。

正解就是扩展一下,记 \(T(u)\) 表示 \(u\) 的子树。记 \(d[u]\) 为 \(T(u)\) 能向上传的最大权值的链。(抛开能计算贡献的链)

\(d[u]\) 和 贡献 靠 \(multiset\) 维护即可。按权值从小到大枚举链,找最小的能和它匹配的链, 匹配后把他们从集合里删掉。

细节是如果 单链权值 就 \(\ge lim\) 就不要放进集合了直接算贡献。

反思一下,对 \(multiset\) 操作太不熟了,有点儿难调。。。代码能力还能提升!

#include<bits/stdc++.h>
#define F(i,l,r) for (int i(l); i<=(r); ++i)
#define G(i,r,l) for (int i(r); i>=(l); --i)
using namespace std;
using ll = long long;
const int N = 1e6 + 5;
bool vis[N];
struct node{
int v,w,ne;
}e[N << 1];
int n, m, idx = 0, num = 0;
int mx[N], first[N], d[N];
void add(int x, int y, int z){
e[++idx] = (node){y, z, first[x]};
first[x] = idx;
}
void go(int u, int f, int lim){
multiset<int> p;
for(int i = first[u]; i; i = e[i].ne){
int v = e[i].v, w = e[i].w;
if(v == f) continue;
go(v, u, lim);
if(d[v] + w>=lim) ++num;
else p.insert(d[v] + w);
}
while(p.size()){
int x = *p.begin();
p.erase(p.begin());
auto it = p.lower_bound(lim - x);
if(it != p.end()){
++ num;
p.erase(it);
}
else d[u] = max(x, d[u]);
}
}
inline bool chk(int lim){
memset(d, 0, sizeof(d));
num = 0;
go(1, 0, lim);
return num >= m;
}
signed main(){
// freopen("track.in","r",stdin);
// freopen("track.out","w",stdout);
ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
cin >> n >> m;
F(i, 1, n - 1){
int u, v, w;
cin >> u >> v >> w;
add(u, v, w);
add(v, u, w);
}
int l = 0, r = 5e8 + 1, mid;
while(l + 1 < r){
mid = (l + r) >> 1;
if(chk(mid)) l = mid;
else r = mid;
}
cout << l << '\n';
return fflush(0),0;
}

NOIP2018 提高组 旅行

树的情况:从1开始,每次按点权从小到大扩展即可(预先对邻接表sort)。

基环树:只有一个环,断一条边就是树,环上每条边都尝试一下即可。时间复杂度 \(O(n^2)\)。

#include<bits/stdc++.h>
#define F(i,l,r) for(int i(l);i<=(r);++i)
using namespace std;
using ll = long long;
const int N = 5e3 + 5;
struct node{
int u, v;
inline bool operator == (const node &o){
return u == o.u && v == o.v;
}
}e[N], d[N];
vector<int> G[N];
int n, m, cnt = 0, num = 0, tot = 0;
int dfn[N], low[N], nw[N], ans[N];
bool ins[N];
stack<int> stk;
inline void dfs(int u, int f){
ans[++tot] = u;
for(auto v : G[u]){
if(v == f) continue;
dfs(v, u);
}
}
inline void tarjan(int u, int f){
stk.push(u),ins[u] = 1,dfn[u] = low[u] = ++cnt;
for(auto v : G[u]){
if(v == f) continue;
if(!dfn[v]) tarjan(v, u), low[u] = min(low[u], low[v]);
else if(ins[v]) low[u] = min(low[u], dfn[v]);
}
if(low[u] == dfn[u]){
int x, las = 0, fst = 0;
if(stk.top() == u) return stk.pop(), ins[u] = 0, void();
do{
x = stk.top(),stk.pop(),ins[x] = 0;
if(las) d[++ num] = {las, x};
else fst = x;
las = x;
}while(x != u);
d[++ num] = {u, fst};
}
}
inline void dfs(int u, int f, int idx){
nw[++ tot] = u;
for(auto v : G[u]){
if(v == f || (d[idx] == (node){u, v}) || (d[idx] == (node){v, u})) continue;
dfs(v, u, idx);
}
}
signed main(){
// freopen("travel.in","r",stdin);
// freopen("travel.out","w",stdout);
ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
cin >> n >> m;
if(m == n - 1){
F(i, 1, m){
int u, v;
cin >> u >> v;
G[u].push_back(v);
G[v].push_back(u);
} F(u, 1, n) if(G[u].size()) sort(G[u].begin(), G[u].end());
dfs(1, 0);
}
else{
F(i, 1, m) cin >> e[i].u >> e[i].v, G[e[i].u].push_back(e[i].v), G[e[i].v].push_back(e[i].u);
tarjan(1, 0);
F(u, 1, n) if(G[u].size()) sort(G[u].begin(), G[u].end());
F(i, 1, num){
tot = 0, dfs(1, 0, i);
if(ans[1]){
F(j, 1, n) {
if(ans[j] == nw[j]) continue;
if(ans[j] > nw[j]){
F(k, 1, n) ans[k] = nw[k];
break;
}
else break;
}
} else F(j, 1, n) ans[j] = nw[j];
}
} F(i, 1, tot) cout << ans[i] << ' ';
return fflush(0), 0;
}

【2024.09.27】NOIP2024 赛前集训-刷题训练(3)的更多相关文章

  1. NOIp2018停课刷题记录

    Preface 老叶说了高中停课但是初中不停的消息后我就为争取民主献出一份力量 其实就是和老师申请了下让我们HW的三个人听课结果真停了 那么还是珍惜这次机会好好提升下自己吧不然就\(AFO\)了 Li ...

  2. LeetCode的刷题利器(伪装到老板都无法diss你没有工作)

    在工程效率大行其道的今天,如果不会写点代码以后也不容易在测试圈混下去.今天给大家推荐一个LeetCode的刷题利器,可以伪装到连你老板在这里走过去都无法确认你是在干活呢,还是在干活呢. LeetCod ...

  3. leecode刷题(27)-- 合并k个排序链表

    leecode刷题(27)-- 合并k个排序链表 合并k个排序链表 合并 k 个排序链表,返回合并后的排序链表.请分析和描述算法的复杂度. 示例: 输入: [ 1->4->5, 1-> ...

  4. 牛客网NOIP赛前集训营-提高组(第四场)B题 区间

    牛客网NOIP赛前集训营-提高组(第四场) 题目描述 给出一个序列 a1, ..., an. 定义一个区间 [l,r] 是好的,当且仅当这个区间中存在一个 i,使得 ai 恰好等于 al, al+1, ...

  5. NOI Online 赛前刷题计划

    Day 1 模拟 链接:Day 1  模拟 题单:P1042 乒乓球  字符串 P1015 回文数  高精 + 进制 P1088 火星人  搜索 + 数论 P1604 B进制星球  高精 + 进制 D ...

  6. ZJOI2019一轮停课刷题记录

    Preface 菜鸡HL终于狗来了他的省选停课,这次的时间很长,暂定停到一试结束,不过有机会二试的话还是可以搞到4月了 这段时间的学习就变得量大而且杂了,一般以刷薄弱的知识点和补一些新的奇怪技巧为主. ...

  7. NOIP赛前集训备忘录(含每日总结)(日更?。。。)

    NOIP赛前集训备忘录(含每日考试总结) 标签: 有用的东西~(≧▽≦)/~啦啦啦 阅读体验:https://zybuluo.com/Junlier/note/1279194 考试每日总结(这个东西是 ...

  8. Buu刷题

    前言 希望自己能够更加的努力,希望通过多刷大赛题来提高自己的知识面.(ง •_•)ง easy_tornado 进入题目 看到render就感觉可能是模板注入的东西 hints.txt给出提示,可以看 ...

  9. 《剑指offer》刷题笔记

    简介 此笔记为我在 leetcode 上的<剑指offer>专题刷题时的笔记整理. 在刷题时我尝试了 leetcode 上热门题解中的多种方法,这些不同方法的实现都列在了笔记中. leet ...

  10. 《剑指offer》刷题目录

    <剑指offer>刷题目录 面试题03. 数组中重复的数字 面试题04. 二维数组中的查找 面试题05. 替换空格 面试题06. 从尾到头打印链表 面试题07. 重建二叉树 面试题09. ...

随机推荐

  1. EF Core 索引器属性(Indexer property)场景及应用

    EF Core 索引器属性(Indexer property)场景及应用 简介 EF Core 中的索引器属性(Indexer Property)是指通过一个特殊的属性来访问实体类中的数据,而不必明确 ...

  2. springcloud feign集成hystrix

    本章介绍feign集成hystrix 1.增加pom依赖` <dependency> <groupid>org.springframework.cloud</groupi ...

  3. MFC状态栏的创建与添加进度条

    1.首先要创建状态栏 MFC中创建状态栏是用数组来分隔格子的.所以要先弄个数组 下面在自己继承的CWnd类.cpp文件中定义一个静态数组indicators static UINT indicator ...

  4. 华为交换机S5700-52C-EI开启ssh服务

    参考资料 https://blog.csdn.net/qq_34815358/article/details/83865527 https://www.cnblogs.com/Cyanix/p/999 ...

  5. 后缀数组--SA--字符串

    SA (Suffix Array) -- 后缀数组 简介 这里明白两个定义: \(SA_i\) : 按字典序排列后大小为 \(i\) 的后缀的后缀头的下标. \(Rank_i\) : 后缀头的下标为 ...

  6. Java Script网页设计案例

    1. JavaScript网页设计案例 下面我将提供一个简单的JavaScript网页设计案例,该案例将实现一个动态的待办事项列表(Todo List).用户可以在页面上添加新的待办事项,标记它们为已 ...

  7. 日志与追踪的完美融合:OpenTelemetry MDC 实践指南

    前言 在前面两篇实战文章中: OpenTelemetry 实战:从零实现分布式链路追踪 OpenTelemetry 实战:从零实现应用指标监控 覆盖了可观测中的指标追踪和 metrics 监控,下面理 ...

  8. webpack系列-externals配置使用(CDN方式引入JS)

    如果需要引用一个库,但是又不想让webpack打包(减少打包的时间),并且又不影响我们在程序中以CMD.AMD或者window/global全局等方式进行使用(一般都以import方式引用使用),那就 ...

  9. webpack笔记-生产环境与开发环境常用plugin介绍(五)

    mode 和 plugin 前边我们介绍 mode 时提过,mode 不同值会影响 webpack 构建配置,其中有一个就是会启用 DefinePlugin 来设置process.env.NODE_E ...

  10. DOM – MutationObserver

    介绍 它和 IntersectionObserver, ResizeObserver 差不多, 都是观察 element 变化的. 它可以观察元素的 attribute 增加, 移除, 修改, app ...