首页 > 其他分享 >[赛记] 多校A层冲刺NOIP2024模拟赛11 && 12

[赛记] 多校A层冲刺NOIP2024模拟赛11 && 12

时间:2024-10-24 19:47:50浏览次数:1  
标签:11 cnt 赛记 int sum 多校 up 序列 include

冒泡排序 100pts

比较显然的签到题 (好久没这么水过了)

考虑这个错的冒泡排序,手模一下即可发现这个 $ +k $ 有点像以前做过的同余系中求和的问题,于是这个题同理,用 set 维护每个同余系的排名,最后按顺序输出即可;

对于正确性,相当于每次 $ +k $,则就相当于在一个同余系中排序;

时间复杂度:$ \Theta(n \log n) $;

点击查看代码
#include <iostream>
#include <cstdio>
#include <set>
using namespace std;
int n, k;
int a[5000005], ans[5000005];
multiset<int> s;
int main() {
	freopen("bubble.in", "r", stdin);
	freopen("bubble.out", "w", stdout);
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin >> n >> k;
	for (int i = 1; i <= n; i++) {
		cin >> a[i];
	}
	for (int i = 1; i <= k; i++) {
		s.clear();
		for (int j = i; j <= n; j += k) {
			s.insert(a[j]);
		}
		for (int j = i; j <= n; j += k) {
			ans[j] = *s.begin();
			s.erase(s.begin());
		}
	}
	for (int i = 1; i <= n; i++) cout << ans[i] << ' ';
	return 0;
}

染色 4pts

给了1G原来是用在了bitset上

转化题意:对于最终的序列,如1 1 1 1 1 2 2 3 3 3,将其去重后变为 1 2 3,则其合法当其为原序列 $ a $ 的子序列时;

正确性很正确(但确实想不到)

那么设 $ f_i $ 表示长度为 $ i $ 的本质不同的子序列个数,那么最终的答案即为 $ \sum_{i = 1}^{n} C_{n - 1}^{i - 1} f_i $;

证明考虑插板法;

那么我们的问题变为了求本质不同的子序列个数,但是子序列的任意相邻两项不相等;

发现原来的不太好转移,那么多开一维,设 $ f_{i, j} $ 表示长度为 $ i $,结尾是 $ j $ 的本质不同的子序列个数,则有转移:$ f_{i, a_i} = \sum_{j = 1}^{m} f_{i - 1, j} \ (j \not= a_i) $;

那么这东西是 $ \Theta(nm) $ 的,发现长度只能是 $ 0 \ 1 $,于是我们可以将 $ i $ 这一维用 bitset 优化,复杂度 $ \Theta(\frac{nm}{w}) $;

具体实现上需要注意一些细节,比如 $ f_{i, j} $ 的基础为 $ 1 $,我们要加上这个 $ 1 $,再如维护 $ \sum_{j = 1}^{m} f_{i - 1, j} $ 时需要先减去 $ f_j $ 再更新 $ f_j $;

有一些技巧:模 $ 2 $ 意义下的的加减操作相当于异或(奇数 + 奇数 = 偶数,剩下的都是奇数),$ C_{n}^{m} \mod 2 = [(n \ \And \ m) = m] $(证明考虑Lucas);

点击查看代码

这场挂分挺多,算是给后天攒RP了吧

Alice 和璀璨花 100pts

树状数组维护最长上升子序列,时间复杂度 $ \Theta(n \log n) $;

注意要先离散化,然后发现乘积项无法离散化,不过没有关系,直接将其赋值到比它小于等于的那个位置即可(因为求的是最长上升子序列所以没有影响,但如果这题求得是最长不下降可能就得用权值线段树了,时间复杂度 $ \Theta(n \log V) $,其中 $ V $ 为值域);

点击查看代码
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
int n;
long long a[1000005], b[1000005], c[5000005], f[1000005];
int cnt;
namespace BIT{
	inline int lowbit(int x) {
		return x & (-x);
	}
	long long tr[5000005];
	void add(int pos, long long d) {
		for (int i = pos; i <= cnt; i += lowbit(i)) tr[i] = max(tr[i], d);
	}
	long long ask(int pos) {
		long long ans = 0;
		for (int i = pos; i; i -= lowbit(i)) ans = max(ans, tr[i]);
		return ans;
	}
}
using namespace BIT;
long long ans;
int main() {
	freopen("alice.in", "r", stdin);
	freopen("alice.out", "w", stdout);
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin >> n;
	for (int i = 1; i <= n; i++) {
		cin >> a[i];
		c[++cnt] = a[i];
	}
	for (int i = 1; i <= n; i++) {
		cin >> b[i];
		c[++cnt] = b[i];
	}
	c[++cnt] = 0;
	c[++cnt] = -1;
	sort(c + 1, c + 1 + cnt);
	cnt = unique(c + 1, c + 1 + cnt) - c - 1;
	for (int i = 1; i <= n; i++) {
		f[i] = ask(lower_bound(c + 1, c + 1 + cnt, a[i]) - c - 1) + 1;
		ans = max(ans, f[i]);
		int pos = lower_bound(c + 1, c + 1 + cnt, a[i] * b[f[i]]) - c;
		if (c[pos] != a[i] * b[f[i]]) pos--;
		add(pos, f[i]);
	}
	cout << ans;
	return 0;
}

David 与和谐号 8pts

呵呵,部分分暴搜,正解就换了种搜+剪了个枝;

好吧暴搜挂完了,36pts -> 8pts,调参少了一个;

正解是迭代加深搜索,并且剪了个枝;

发现我们的搜索树可能会很深,但答案很浅,所以可以迭代加深搜索(IDA*);

所谓IDA*,即每次固定一个搜索上界(设为 $ up $ ),超了就返回;

对于这个题,还有一个剪枝,就是当当前搜索到的深度的估价函数 $ D(x) $ 加上当前搜索位置大于我们所规定的上界时就返回;

$ D(x) $ 怎么算?发现当前状态中,如果相邻两项 $ a_i, a_{i - 1} $ 的差 $ | a_i - a_{i - 1} | \geq 2 $ 就至少要转一次。那么记这种状态的出现次数为 $ sum $,则 $ D(x) = sum $;

所以当 $ D(x) + x > up $ 时就返回,这样就能过了;

时间复杂度:$ \Theta(能过) $;

注意在判断 $ D(x) + x > up $ 时先判断 $ x > up $ 的情况,或者直接在更新答案之前判断 $ D(x) + x > up $ 的情况也行;

点击查看代码
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
int t;
int n;
int a[55];
int ans;
void dfs(int x, int ls, int up, int sum) {
	if (ans <= x - 1) return;
	if (x - 1 > up) return;
	bool vis = true;
	for (int i = 1; i <= n; i++) {
		if (a[i] != i) {
			vis = false;
			break;
		}
	}
	if (vis) {
		ans = min(ans, x - 1);
		return;
	}
	if (x - 1 + sum > up) return;
	for (int i = 2; i <= n; i++) {
		if (i == ls) continue;
		int now = sum + ((i < n) && (abs(a[i] - a[i + 1])) == 1) - ((i < n) && abs(a[1] - a[i + 1]) == 1);
		reverse(a + 1, a + 1 + i);
		dfs(x + 1, i, up, now);
		reverse(a + 1, a + 1 + i);
	}
}
int main() {
	freopen("david.in", "r", stdin);
	freopen("david.out", "w", stdout);
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin >> t;
	while(t--) {
		cin >> n;
		for (int i = 1; i <= n; i++) cin >> a[i];
		bool vis = true;
		for (int i = 1; i <= n; i++) {
			if (a[i] != i) {
				vis = false;
				break;
			}
		}
		if (vis) {
			cout << 0 << '\n';
			continue;
		}
		int sum = 0;
		for (int i = 2; i <= n; i++) {
			if (abs(a[i] - a[i - 1]) >= 2) sum++;
		}
		ans = 0x3f3f3f3f;
		int i = 1;
		while(ans == 0x3f3f3f3f && i <= 2 * n + 2) {
			dfs(1, 0, i, sum);
			i++;
		}
		cout << ans << endl;
	}
	return 0;
}

标签:11,cnt,赛记,int,sum,多校,up,序列,include
From: https://www.cnblogs.com/PeppaEvenPig/p/18500356

相关文章

  • 基于Java的高校成绩报送系统的设计与实现(11870)
     有需要的同学,源代码和配套文档领取,加文章最下方的名片哦一、项目演示项目演示视频二、资料介绍完整源代码(前后端源代码+SQL脚本)配套文档(LW+PPT+开题报告)远程调试控屏包运行三、技术介绍Java语言SSM框架SpringBoot框架Vue框架JSP页面Mysql数据库IDEA/Eclipse开发四、项......
  • 多校A层冲刺NOIP2024模拟赛12
    多校A层冲刺NOIP2024模拟赛12\(T1\)A.Alice和璀璨花\(65pts/65pts/65pts\)部分分测试点\(1\sim10\):设\(f_{i,j}\)表示前\(i\)位中生长趋势子序列长度为\(j\)时的末尾最小元素,然后进行暴力转移。测试点\(11\sim13\):观察到至多选择\(\left\lceil\log_......
  • 2024牛客暑期多校训练营9 B.Break Sequence
    设\(f_i\)表示最后一个区间以\(a_i\)结尾的方案总数,也即前\(i\)个数的方案总数。最后的答案是\(f_n\)。很容易得到转移方程:\[f_i=\sum_{j=1}^{i-1}f_j\]其中,需要保证\(a_i\sima_j\)是一个合法区间才能累加,这个检查的过程可以通过\(j\)倒序并计算不合法的数的个......
  • 『模拟赛』多校A层冲刺NOIP2024模拟赛12
    Rank挂了不少,还行A.Alice和璀璨花签。一眼最长上升子序列,昨天在AT专题里刚见过,不过赛时没想到离散化之后树状数组,所以打的动态开点,结果细节挂了30pts。和最长上升子序列思路基本一致,直接区间查询\([1,a_i-1]\)的最大值,然后在\(a_i\timesb_{f_i}\)插入\(f_i\)......
  • CF1139C. Edgy Trees 题解 并查集
    题目链接:https://codeforces.com/problemset/problem/1139/C视频讲解:https://www.bilibili.com/video/BV1tZ1FYPELp?p=3我们可以求总方案数-不满足条件的方案数。设一个不包含黑色边的极大连通块的大小为\(sz_i\)。则答案为\[n^k-\sum\{sz_i^k\}\]示例程序:#include......
  • [SDOI]2011计算器
    \(非常简单的一道板子训练题\)\(对于问题一:直接使用快速幂解决\)\(对于问题二:使用exgcd解决\)\(对于问题三:使用bsgs解决\)\(code:\)点击查看代码#include<bits/stdc++.h>#defineintlonglong#defineall(x)x.begin(),x.end()#definerall(x)x.rbegin(),x.rend()#d......
  • C++11新特性:lambda表达式
    lambda表达式目录lambda表达式常见lambda表达式的省略式值的捕获lambda表达式的类型使用场景简述附:lambda的常量性......
  • [C++]在windows基于C++编程署yolov11-pose的openvino姿态估计模型cmake项目部署演示源
    【算法介绍】在Windows系统上,基于C++编程部署YOLOv11-Pose的OpenVINO姿态估计模型,可以通过CMake项目来实现。以下是简要介绍:首先,需要准备开发环境,包括安装OpenVINOToolkit、CMake、OpenCV和C++编译器(如GCC或MSVC)。OpenVINO是英特尔开发的一款用于优化和部署深度学习模型的工具套件......
  • [C++]在windows基于C++编程署yolov11-cls的openvino图像分类模型cmake项目部署演示源
    【算法介绍】在Windows系统上,基于C++编程部署YOLOv11-CLS的OpenVINO图像分类模型,可以通过CMake项目来实现。以下是简要介绍:首先,需要准备开发环境,包括安装OpenVINOToolkit、CMake、OpenCV和C++编译器(如GCC或MSVC)。OpenVINO是英特尔开发的一款用于优化和部署深度学习模型的工具套件,......
  • 最新开发项目多校园跑腿小程序源码系统 带完整的安装代码包以及搭建部署教程
    系统概述随着移动互联网技术的快速发展,校园跑腿服务因其便捷性和高效性受到了越来越多学生的青睐。然而,目前市场上的跑腿小程序大多存在功能单一、操作复杂、用户体验差等问题。为了填补这一市场空白,我们开发了这款多校园跑腿小程序源码系统,旨在为学生提供更便捷、高效、可靠......