首页 > 其他分享 >盖世计划--0806--B班训练

盖世计划--0806--B班训练

时间:2024-08-06 21:54:24浏览次数:7  
标签:std -- 0806 long i64 int 盖世 using define

A

我的题解

B

神秘题

根据 2008 年集训队论文可以给出 \(O(n)\) 做法,不会。

考虑从 \(k\) 小的情况出发。

当 \(k=1\) 时,结论:当且仅当 \(n\) 为 \(2\) 的幂次时,先手必败。可以通过二进制构造方案求解。

当 \(k=2\) 时,结论:当且仅当 \(n\) 为斐波那契数时先手必败。将每个数通过斐波那契数分解,用 \(k=1\) 的方法证明。

否则,我们希望能够将 \(n\) 通过某个神秘序列分解,使得用 \(k=1\) 的方法先手能够必胜。

这个神秘序列满足:

  1. 可以将 \(n\) 分解为若干数,使得排序后相邻数至少为 \(k\) 倍关系。

然后大力构造。

#include <bits/stdc++.h>
#define pii std::pair<int, int>
#define mk std::make_pair
#define fi first
#define se second
#define pb push_back

using i64 = long long;
using ull = unsigned long long;
const i64 iinf = 0x3f3f3f3f, linf = 0x3f3f3f3f3f3f3f3f;
/*

*/
const int N = 2e7 + 10;
int a[N], b[N];
int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    
	int n, k;
	std::cin >> n >> k;

	a[0] = b[0] = 1;
	int i = 0, j = 0;
	while(a[i] < n) {
		i++;
		a[i] = b[i - 1] + 1;
		while(a[j] * k < a[i]) j++;
		j--;
		if(a[j] * k < a[i]) b[i] = b[j] + a[i];
		else b[i] = a[i];
	}

	if(a[i] == n) {
		std::cout << "lose\n";
		return 0;
	}

	i--;
	while(n) {
		if(n == a[i]) break;
		if(n > a[i]) n -= a[i];
		i--;
	}

	std::cout << a[i] << "\n";

	return 0;
}

C

博弈论

每个点都有必胜或必败状态,可以线性求出。

如果原本 \(\texttt{Alice}\) 就能赢,那么代价为 \(0\)。

否则加边。首先加边不能构成环,不然会平局。

然后起点在加边后能够到达,终点的状态一定是先手必败。

总结一下,合法的加边满足:

  1. 不连向祖先
  2. 起点在加边后能够到达
  3. 终点的状态一定是先手必败

2 情况的解决方法是模拟博弈的过程。假如已知起点,那么终点就是不包含到根路径的,所有状态为必败的,节点的权值最小值。两遍 bfs 解决。

#include <bits/stdc++.h>
#define pii std::pair<int, int>
#define mk std::make_pair
#define fi first
#define se second
#define pb push_back

using i64 = long long;
using ull = unsigned long long;
const i64 iinf = 0x3f3f3f3f, linf = 0x3f3f3f3f3f3f3f3f;
/*

*/
const int N = 1e6 + 10;
i64 T, n, t, A, B, d, ans, mn;
i64 a[N];
i64 f[N], g[N];
std::vector<int> e[N];
i64 mnl[N], mnr[N];
i64 read() {
	i64 x = 0, f = 1;
	char c = getchar();
	while(c < '0' || c > '9') {
		if(c == '-') f = -1;
		c = getchar();
	}
	while(c >= '0' && c <= '9') {
		x = (x << 1) + (x << 3) + (c - '0');
		c = getchar();
	}
	return x * f;
}
i64 dfs1(int u) {
	f[u] = g[u] = 0;
	mnl[u] = linf;
	for(int v : e[u]) {
		mn = std::min(mn, dfs1(v));
		f[u] |= !f[v];
		g[u] += !f[v];
	}
	mnl[u] = mn;
	return std::min(mn, !f[u] ? a[u] : linf);
}
i64 dfs2(int u) {
	mnr[u] = linf;
	for(int i = e[u].size() - 1; i >= 0; i--) {
		int v = e[u][i];
		mn = std::min(mn, dfs2(v));
	}
	mnr[u] = mn;
	return std::min(mn, !f[u] ? a[u] : linf);
}
void imit(int u, int now) {
	if(!now) {
		if(std::min(mnl[u], mnr[u]) != linf) ans = std::min(ans, A * a[u] + B * std::min(mnl[u], mnr[u]));
	}
	for(int v : e[u]) {
		if((g[u] == 1 && !f[v]) || !now) {
			imit(v, now ^ 1);
		}
	}
} 
void fake_main() {
	d = 0, ans = linf;
	n = read(), t = read(), A = read(), B = read();
	for(int i = 2; i <= n; i++) {
		int fa = read();
		e[fa].pb(i);
	}
	for(int i = 1; i <= n; i++) a[i] = read();
	mn = linf, dfs1(1);
	mn = linf, dfs2(1); 

	if((!t && f[1]) || (t && !f[1])) {
		printf("0\n");
		for(int i = 1; i <= n; i++) e[i].clear();
		return;
	} 
	imit(1, t);

	printf("%lld\n", (ans != linf) ? ans : -1);
	for(int i = 1; i <= n; i++) e[i].clear();
}	
int main() {

	// T = read(); 
	T = 1;
	while(T--) fake_main();

	return 0;
}

D

计数题,首先不考虑第二个限制,可以设 \(g_{i,j}\) 求出 \(i\) 个球,\(j\) 种颜色的方案数。

然后设 \(f_{i,j}\) 表示前 \(i\) 层,第 \(i\) 层 \(j\) 种颜色的方案数。

预处理排列数和阶乘就做完了。

#include <bits/stdc++.h>
#define pii std::pair<int, int>
#define mk std::make_pair
#define fi first
#define se second
#define pb push_back

using i64 = long long;
using ull = unsigned long long;
const i64 iinf = 0x3f3f3f3f, linf = 0x3f3f3f3f3f3f3f3f;
/*

*/
const int N = 1e6 + 10, M = 5e3 + 10;
i64 n, m, p, maxn, sum;
i64 l[N];
i64 A[M], fac[M], g[M][M], f[2][M];
int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    
	std::cin >> n >> m >> p;

	for (int i = 1; i <= n; i++) std::cin >> l[i], maxn = std::max(maxn, l[i]);

	A[0] = 1;
	for(int i = 1; i <= maxn; i++) A[i] = A[i - 1] * (m - i + 1) % p;
	fac[0] = 1;
	for(int i = 1; i <= maxn; i++) fac[i] = fac[i - 1] * i % p;

	g[0][0] = 1;
	for(int i = 1; i <= maxn; i++) {
		for(i64 j = 1; j <= maxn; j++) {
			g[i][j] = (g[i - 1][j] * (j - 1) % p + g[i - 1][j - 1]) % p;
		} 
	}

	int lst = 1, cur = 0;
	sum = 1;
	for(int i = 1; i <= n; i++) {
		std::swap(lst, cur);
		for(int j = 1; j <= std::min(m, l[i]); j++) {
			f[cur][j] = (A[j] * g[l[i]][j] % p * sum % p - fac[j] * g[l[i]][j] % p * f[lst][j] % p + p) % p;
		}
		sum = 0;
		for(int j = 1; j <= std::min(m, l[i]); j++) sum = (sum + f[cur][j]) % p;
		for(int j = 1; j <= l[i - 1]; j++) f[lst][j] = 0;
	}

	std::cout << sum << "\n";

	return 0;
}

E

不合法的数只有一种,考虑贪心地,把不合法的数尽可能多的并到合法的数中,假设不合法的数为 \(s\),总数为 \(n\),那么最多能并 \(n-s+1\) 个,剩下的不合法的分为一个一个。

线段树维护区间绝对众数。

#include <bits/stdc++.h>
#define pii std::pair<int, int>
#define mk std::make_pair
#define fi first
#define se second
#define pb push_back

using i64 = long long;
using ull = unsigned long long;
const i64 iinf = 0x3f3f3f3f, linf = 0x3f3f3f3f3f3f3f3f;
/*

*/
const int N = 1e6 + 10;
int n, q;
struct seg {
	int v, c;
} t[N << 2];
std::vector<int> v[N];
int a[N];
void pushup(seg &u, seg ls, seg rs) {
	if(ls.v == rs.v) {
		u.v = ls.v, u.c = ls.c + rs.c;
	} else if(ls.c < rs.c) {
		u.v = rs.v, u.c = rs.c - ls.c;
	} else {
		u.v = ls.v, u.c = ls.c - rs.c;
	}
}
void build(int u, int l, int r) {
	if(l == r) {
		t[u] = {a[l], 1};
		return;
	}
	int mid = (l + r) >> 1;
	build(u << 1, l, mid), build(u << 1 | 1, mid + 1, r);
	pushup(t[u], t[u << 1], t[u << 1 | 1]);
}
seg qry(int u, int l, int r, int L, int R) {
	if(L <= l && r <= R) return t[u];
	int mid = (l + r) >> 1;
	if(R <= mid) return qry(u << 1, l, mid, L, R);
	if(L > mid) return qry(u << 1 | 1, mid + 1, r, L, R);
	seg ret = {0, 0}, ls = qry(u << 1, l, mid, L, R), rs = qry(u << 1 | 1, mid + 1, r, L, R);
	pushup(ret, ls, rs);
	return ret;
}
int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    
	std::cin >> n >> q;

	for(int i = 1; i <= n; i++) {
		std::cin >> a[i];
		v[a[i]].pb(i);
	}
	build(1, 1, n);

	while(q--) {
		int l, r;
		std::cin >> l >> r;
		int x = qry(1, 1, n, l, r).v;
		int sum = std::upper_bound(v[x].begin(), v[x].end(), r) - 1 - std::lower_bound(v[x].begin(), v[x].end(), l) + 1;
		if(sum <= (r - l + 2) / 2) std::cout << "1\n";
		else {
			std::cout << 1 + (sum - (r - l + 1 - sum + 1)) << "\n";
		}
	}

	return 0;
}

F

鸽。

标签:std,--,0806,long,i64,int,盖世,using,define
From: https://www.cnblogs.com/FireRaku/p/18346067

相关文章

  • LangChain与CI/CD的无缝对接:自动化部署的新前沿
    LangChain与CI/CD的无缝对接:自动化部署的新前沿在当今快速发展的软件开发领域,持续集成/持续部署(CI/CD)已成为提升开发效率和软件质量的关键实践。LangChain,作为一个假设的编程辅助工具,如果存在,它可能会与CI/CD流程紧密集成,以实现代码生成、测试和部署的自动化。本文将探讨La......
  • 《LeetCode热题100》---<5.②普通数组篇五道>
    本篇博客讲解LeetCode热题100道普通数组篇中的五道题第三道:轮转数组(中等)第四道:除自身以外数组的乘积(中等)第三道:轮转数组(中等) 方法一:使用额外的数组classSolution{publicvoidrotate(int[]nums,intk){intlen=nums.length;int[]newAr......
  • WSL2Linux 子系统(九)
    WSL挂载硬盘/U盘/SD卡上一篇文章《WSL2Linux子系统(八)》讲解WSL与Windows之间端口转发规则和正向端口代理。《WSL2Linux子系统(六)》中仅仅简单讲解WSL(WindowsSubsystemforLinux)挂载硬盘,本篇继续详细讲解几种常见硬盘挂载使用。挂载外部硬盘到WSL不仅可以扩......
  • python爬虫预备知识三-多进程
    python实现多进程的方法:fork、multiprocessing模块创建多进程。os.fork方法os.fork方法只适合于unix/linux系统,不支持windows系统。fork方法调用一次会返回两次,原因在于操作系统将当前进程(父进程)复制出一份进程(子进程),这两个进程几乎完全相同,fork方法分别在父进程和子进程中......
  • C语言典型例题28
    《C程序设计教程(第四版)——谭浩强》习题2.5输入一个华氏温度,要求输出摄氏温度。公式为C=5/9(F-32),要求输出要有文字说明,取两位小数数学知识:(1)华氏温度与摄氏温度(FahrenheittemperatureandCelsiustemperature),是两大国际主流的计量温度的标准。(2)华氏温标由来华氏温标:......
  • PEP 8 – Python 代码风格指南中文版(七)
    编程建议(2) 定义异常时,应该从Exception类继承,而不是从BaseException类继承。直接从BaseException继承的异常通常是那些几乎不应该被捕获的异常。设计异常层次结构时,应该基于捕获异常的代码可能需要进行的区分,而不是基于异常被抛出的位置。目标是通过编程方式回答“出了......
  • JavaScript (二十六)——JavaScript 代码规范
    目录JavaScript代码规范变量名空格与运算符代码缩进语句规则对象规则每行代码字符小于80命名规则HTML载入外部JavaScript文件文件扩展名所有的JavaScript项目适用同一种规范。JavaScript代码规范代码规范通常包括以下几个方面:变量和函数的命名规则......
  • 爬虫简易说明
    想必大家都了解爬虫,也就是爬取网页你所需要的信息相比于网页繁多的爬虫教程,本篇主要将爬虫分为三个部分,以便你清楚,代码的功能以及使用,这三部分分别为1.获取到源代码2.根据网页中的标签特征,获取源代码你所需要的部分3.想一下如何根据页面的逻辑将一系列的网页自动化抓取接下来......
  • 系统特殊权限
    系统特殊权限1.Linux****系统特殊权限-rwsr-xr-x.1rootroot54080Nov52016/usr/bin/catroot⽤户执⾏cat,最终运⾏的身份是rootbgx⽤户执⾏cat,最终运⾏的身份是bgxsuidroot⽤户执⾏,最终运⾏的身份是rootbgx⽤户执⾏,最终运⾏的身份是root如何设置特殊权限⽤符......
  • JavaWeb中的Tomcat,Servlet详解
    JavaWebJavaWeb技术主要包括服务器技术(后端),如Tomcat,Servlet,JSP等待,以及客户端技术(前端)如HTML,CSS,JavaScript等等Web服务器Web服务器主要负责处理客户端发出的HTTP请求,并做出相应回应Web服务器:安装了服务器软件的计算机,只用于复杂处理请求,发出相应Web服务器......