首页 > 其他分享 >2024.8.23 模拟赛总结

2024.8.23 模拟赛总结

时间:2024-08-23 08:58:02浏览次数:8  
标签:fx 23 2024.8 fy int fa siz 模拟 mathrm

A.dist

Statement:

给定一棵 \(n(n \le 10^6)\) 个节点带边权的树,定义 \(\mathrm{Min}(x, y)\) 是 \((x, y)\) 路径上的边权最小值。求 \(\max_{r = 1}^n {\sum_{v \ne i} \mathrm{Min}(r, v)}\)。

Solution:

经典套路题。

首先注意到一条路径上的只有最小值才会产生贡献,于是对于一个连通块,我们找到最小的那个边,并分成两个连通块 \(\mathrm{A, B}\),假如把根放在 \(\mathrm A\) 中,那么对于连通块 \(\mathrm B\) 到根的所有路径贡献都是这个最小边的边权,然后递归计算 \(\mathrm A\) 的贡献,对于放在 \(\mathrm B\) 中的情况一样做即可。但是这样的时间复杂度是 \(O(n^2)\) 的。

于是将删边改成加边,具体的,我们将边按边权从大到小排序,每次合并两个集合,用个并查集维护即可。时间复杂度 \(O(n \log n)\)。

qwq
#include<bits/stdc++.h>
#pragma GCC optimize(3, "Ofast", "inline")
#define int long long
using namespace std;

const int N = 1e6 + 10;

int n, fa[N], siz[N], val[N];
struct Edge{
	int u, v, w;
}E[N];
bool cmp(struct Edge E1, struct Edge E2){
	return E1.w > E2.w;
}
int findfa(int x){return fa[x] = (fa[x] == x) ? x : findfa(fa[x]);}

void merge(int x, int y, int w){
	int fx = findfa(x), fy = findfa(y);
	if(fx == fy) return; if(siz[fx] < siz[fy]) swap(fx, fy); 
	val[fx] = max(val[fx] + siz[fy] * w, val[fy] + siz[fx] * w);
	fa[fy] = fx; siz[fx] += siz[fy];
}

signed main(){
//	freopen("dist3.in", "r", stdin);
	freopen("a.in", "r", stdin);
	freopen("a.out", "w", stdout);
	ios::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);
	cin >> n; for(int i = 1; i <= n; i++) siz[i] = 1, fa[i] = i;
	for(int i = 1; i < n; i++) cin >> E[i].u >> E[i].v >> E[i].w;
	sort(E + 1, E + n, cmp);
	for(int i = 1; i < n; i++) merge(E[i].u, E[i].v, E[i].w);
	cout << val[findfa(1)];
	
	return 0;
}

B.wolf

Statement:

有 \(n(1 \le n \le 3000)\) 间屋子,由 \(n − 1\) 条双向道路连接成了一个树形结构。其中,第 \(i\) 间屋子里居住了 \(1\) 个种族为 \(c_i\) 的狼人。现在你要召集一个连通块内的狼人。设 \(a_j\) 表示被召集的种族为 \(j\) 的狼人个数,若存在 \(2 a_k > \sum a_j\) ,则种族为 \(k\) 的狼人会造反。你想知道有多少个连通块会使某种狼人造反,答案对 \(998244353\) 取模。

Solution:

首先对判定进行转化:\(2a_k > \sum_{j = 1}^n a_j \Leftrightarrow a_k - \sum_{j \ne k} a_j > 0\)。

所以可以枚举作为众数的种类然后做一遍做一遍树上背包,这样时间复杂度是 \(O(n^3)\)。然后注意到对于一个总共有 \(cnt_i\) 个狼人的种类 \(i\),背包上下限是 \(cnt_i\),由树上背包的时间复杂度做一次是 \(O(ncnt_i)\) 的,于是总复杂度是 \(O(n^2)\) 的了。

qwq
#include<bits/stdc++.h>
#pragma GCC optimize(3, "Ofast", "inline")
#define int long long 
using namespace std;

const int N = 3000 + 10, mod = 998244353;

int n, m, col[N], _col[N], f[N][2 * N], cnt0[N], cnt1[N], ans, tmp[2 * N];

struct edge{
	int v, next;
}edges[N << 1];
int head[N], idx;
int id(int val){if(val < 0) val += 2 * m + 1; return val;}
void ADD(int& x, int y){x = (x + y) % mod;}

void add_edge(int u, int v){
	edges[++idx] = {v, head[u]};
	head[u] = idx;
}
int mymax(int x, int y){return (x > y) ? x : y;}

void dfs(int u, int fa){
	cnt0[u] = (!col[u]); cnt1[u] = col[u]; //f[u][0] = 1;
	for(int i = -m; i <= m; i++) f[u][id(i)] = 0;
	f[u][(cnt0[u] ? id(-1) : 1)] = 1;
//	cout << u << " " << f[u][id(-1)] << " " << f[u][1] << "\n";
	for(int i = head[u]; i; i = edges[i].next){
		int v = edges[i].v; if(v == fa) continue;
		dfs(v, u);
		for(int i = mymax(-m, -cnt0[u]); i <= cnt1[u]; i++) tmp[id(i)] = f[u][id(i)];
		for(int i = mymax(-m, -cnt0[u]); i <= cnt1[u]; i++){
			for(int j = mymax(-m, -cnt0[v]); j <= cnt1[v]; j++){
				if(i + j >= -m && i + j <= m) ADD(f[u][id(i + j)], tmp[id(i)] * f[v][id(j)] % mod);
			}
		}
		cnt1[u] += cnt1[v]; cnt0[u] += cnt0[v];
	}
//	for(int i = mymax(-m, -cnt0[u]); i <= cnt1[u]; i++) cout << u << " " << i << " " << f[u][id(i)] << "\n";
	for(int i = 1; i <= cnt1[u]; i++) ADD(ans, f[u][i]);
}

signed main(){
//	freopen("wolf6.in", "r", stdin);
    freopen("b.in", "r", stdin);
    freopen("b.out", "w", stdout);
	ios::sync_with_stdio(0);
	cin.tie(0); cout.tie(0); 
	cin >> n; for(int i = 1; i <= n; i++) cin >> _col[i];
	for(int i = 1; i < n; i++){
		int x, y; cin >> x >> y;
		add_edge(x, y); add_edge(y, x);
	}
	for(int tcol = 1; tcol <= n; tcol++){
		m = 0;
		for(int i = 1; i <= n; i++) col[i] = (_col[i] == tcol), m += col[i];
		if(m) dfs(1, 0);
	}
	cout << ans;
	
	return 0;
} 

标签:fx,23,2024.8,fy,int,fa,siz,模拟,mathrm
From: https://www.cnblogs.com/little-corn/p/18375106

相关文章

  • WPF 模拟UWP原生窗口样式——亚克力|云母材质、自定义标题栏样式、原生DWM动画 (附我封
    先看一下最终效果,左图为使用亚克力材质并添加组合颜色的效果;右图为MicaAlt材质的效果。两者都自定义了标题栏并且最大限度地保留了DWM提供的原生窗口效果(最大化最小化、关闭出现的动画、窗口阴影、拖拽布局器等)。接下来把各部分的实现一个个拆开来讲讲。一、使用窗口材质特......
  • 移情别恋c++ ദ്ദി˶ー̀֊ー́ ) ——6.vector(模拟实现)
    1.存储结构namespacezone{ template<classT>//需要模板 classvector { public:private: iterator_start; iterator_finish; iterator_endofstorage;};}可见,vector内核是由三个指针实现的2.默认成员函数 2.1.构造函数1.初始化列......
  • P9145 [THUPC 2023 初赛] 世界杯
    [题目通道]([THUPC2023初赛]世界杯-洛谷)简要题意:输出五常中的最强球队。众所周知,每个国家的球队都有自己的长处,在不同规则下最强球队也有所不同。而小M制定的规则是输球场数最少,这是有道理的,因为输球场数可以评判一个球队的稳定性。输球场数越少,就说明稳定性越强,实力......
  • 代码随想录DAY23 - 回溯算法 - 08/22
    组合总和题干题目:给你一个无重复元素的整数数组candidates和一个目标整数target,找出candidates中可以使数字和为目标数target的所有不同组合,并以列表形式返回。你可以按任意顺序返回这些组合。candidates中的同一个数字可以无限制重复被选取。如果至少......
  • YC327B [ 20240821 CQYC NOIP 模拟赛 T2 ] 括号串(bracket)
    题意给定\(S\in\{(,),?\}\)。定义深度为括号嵌套的子序列的最大长度除以\(2\)。求出将\(?\)替换为括号的所有括号串的深度之和,对\(998244353\)取模。\(n\le10^6\)。Sol考虑如何把每次贡献只计算一次。不难想到在括号的中心点计算。可以发现,若当前左右括号......
  • 【C/C++ 软件开发模拟面试 集】cmake 相关知识点模拟面试
    摘自:https://zhuanlan.zhihu.com/p/662623216第一轮:基础知识 1.1什么是CMake? 面试官: 请问你能简单描述一下CMake是什么,以及它通常用来做什么吗? 面试者: CMake是一个跨平台的自动化构建系统,主要用来管理软件构建的过程,它使用一个名为CMakeLists.txt的配置文件来指导编......
  • 幽默重开模拟器
    可以按照人口比例得出的概率预测下一次投胎会在哪个国家或地区。https://wwcl.lanzn.com/igaEE285u2jc密码:gzij居然是自己一个一个复制的国家人口数量代码:#include<iostream>#include<string>#include<vector>#include<random>#include<ctime>#include<cstdlib>typede......
  • 代码随想录Day23
    131.分割回文串给你一个字符串s,请你将s分割成一些子串,使每个子串都是回文串。返回s所有可能的分割方案。示例1:输入:s="aab"输出:[["a","a","b"],["aa","b"]]示例2:输入:s="a"输出:[["a"]]提示:1<=s.length<=16s仅由......
  • 【专题】2023-2024中国游戏企业研发竞争力报告合集PDF分享(附原数据表)
    原文链接: https://tecdat.cn/?p=37447 在当今的数字时代,游戏产业已然成为经济与文化领域中一股不可忽视的重要力量。2023年,中国自研游戏市场更是呈现出一片繁荣且复杂的景象,实际销售收入达到了令人瞩目的2563.8亿元,同比增长15.3%,不仅刷新历史纪录,还彰显出其强大的市场活力......
  • CSP 模拟 26
    T1博弈博弈策略是显然的,只有当所有数的数量全是偶数是,才是后手必胜,考虑随机异或哈希,找一遍后直接统计。T2跳跃容易想到的是一个\(\mathcal{O}(nk)\)的dp,但是带了\(k\),比较难处理。可以这样考虑,最后一定是到了一个位置\(x\),以\(x\)为右端点,在它的区间最大左端点之间反......