首页 > 其他分享 >【2024.09.27】NOIP2024 赛前集训-刷题训练(3)

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

时间:2024-09-27 21:53:11浏览次数:8  
标签:27 cout int lim 2024.09 cin mid using NOIP2024

【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;
}

标签:27,cout,int,lim,2024.09,cin,mid,using,NOIP2024
From: https://www.cnblogs.com/superl61/p/18436651

相关文章

  • 2024/9/27日工作日志
    复习英语单词60个;完成数据结构pta选择题,函数第一题;includeincludeincludeincludeusingnamespacestd;defineOVERFLOW-2typedefintElemType;//ElemType为可定义的数据类型,此设为int类型defineMAXSIZE100//顺序表可能达到的最大长度typedefstruct......
  • 9.27
    1、枚举类型:可以使用“==”和equals()方法直接比对枚举变量的值,是引用类型。2、反码、补码和原码:原码,有符号位和数值部分,0为整数,1为负数。10000101为-5。反码,正数反码与原码相同,负数反码在原码的基础上符号位保持为1,数值部分取反。11111010为-5反码。补码,正数不变,负数为反码加1.11......
  • CSP2024-27
    2A题意:1A题意:给定\(n\timesn\)种物品,\((i,j)\)有\(a_{i,j}\)个,权值为\(b_{i,j}\),两个物品等价当且仅当\(i\)相等或\(j\)相等。初始有一个空(可重)集\(S\),每次等概率从剩余物品中选一个\(x\)出来。如果\(S\)中没有和\(x\)等价的物品,那么\(x\)加入\(S\)......
  • 2024.9.27校测
    T1题目描述\(Mr.Hu\)开了个饭店,来了两位客人:\(Alice\)和\(Bob\),他们吃完饭要结账时,发现他们需要支付\(c\)元钱,但是\(Alice\)只有面值为\(a\)的钱,\(Bob\)只有面值为\(b\)的钱(他们每个人的钱的和都大于\(c\),即可以认为他们有无数张对应面值钱)。现在,\(Mr.Hu\)想知......
  • 2024.9.27
    今天一节课都没去上。反正计概不如自学一点,旷掉也无所谓,感觉。这个比haskell还是有点难绷的,不太懂它都实现了些什么。他要能讲点用这个分析复杂度之类的那还好,但现在的问题是上不去下不来卡在这里了。无论如何把计概作业写了就行。顺便把数算的mooc做了,你12个题我怎么......
  • 9.27 模拟赛(NOIP十三连测 #10)
    2024--梦熊&太戈--NOIP十三连测#10【订正】-比赛-梦熊联盟(mna.wang)复盘开T1。差分转化。模拟了一下样例感觉方案好像是唯一确定的,不需要贪心/DP。但不太能证。想了会感觉找不出反例。然后写完了。对拍没挂。用时不到\(30\)分钟。T2。\(m\le20\)且数据随机感觉很......
  • VMware安装Ubuntu操作系统 2024.9.27
    1.安装Ubuntu的官方网站是:https://www.ubuntu.com/download点进去可以直接下载文件下载会比较慢,我这点用了约5分钟然后就可以打开vmware,选择:就可以注册和使用了。笔记本电脑是这样的。。如果使用台式机,没有相应的硬件环境的话,就不要创建空的盘符了,就可以创建和导入镜像文......
  • 20240927 随机训练
    GYM105350E题目描述给定一个大小为\(N\)的数组\(A\)。我们定义一个大小为\(N\)的数组\(B\)是有效的当且仅当:对于\(\forall1\lei\leN,1\leB_i\leN\),如果从\(B\)中移除\(B_i\),则数组\(B\)恰好有\(A_i\)个不同的数。求有多少个不同的由有效数组\(B\)......
  • GitHub每日最火火火项目(9.27)
    项目名称:localsend/localsend项目介绍:“localsend/localsend”是一个极具价值的开源项目。它为用户提供了一种跨平台的文件传输替代方案,可媲美AirDrop。在当今数字化时代,人们常常需要在不同操作系统的设备之间传输文件,但并非所有设备都能使用AirDrop。这个项目的出......
  • 20240927
    FunisCounting我们可以发现数组\(a\)必须是\(x\)或\(x-1\),然后分类讨论即可#include<bits/stdc++.h>usingnamespacestd;#defineintlonglongconstintN=1e6+5,mod=998244353;intinv[N],f[N],g[N],t,n,a[N];intC(inta,intb){if(......