首页 > 其他分享 >[赛记] csp-s模拟3

[赛记] csp-s模拟3

时间:2024-09-23 20:34:32浏览次数:1  
标签:赛记 fa int sum find dep include csp 模拟

奇观 55pts

赛时打的 $ \Theta(n^5) $ 和 $ m = 0 $ 的特殊性质拿了55pts;

考虑正解,首先,$ CCF $ 这三个字母是可以分开维护的;

对于 $ C $,其可以看作一个连了四个点的线段,对于 $ F $,其可以看作一个连了三个点的线段在再最后分别多连两个点;

设 $ f_{i, j} $ 表示维护一个连了 $ i $ 个点的线段,最后一个点为 $ j $ 时的方案数,有转移:

\[ f_{i, j} = \sum_{k \ is \ connected \ to \ i}^{k \leq n} f_{i - 1, k} \]

这东西可以前缀和维护,然后我们只需维护到 $ i = 4 $ 即可;

最后 $ C $ 直接算,对于 $ F $ 枚举最后一位的数 $ j $,答案即为 $ \sum_{j = 1}^{n} f_{3, j} \times (d_j) ^ 2 $,其中 $ d_j $ 为能与 $ j $ 相连的点数;

点击查看代码
#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
#define int long long
const long long mod = 998244353;
int n, m;
long long f[5][100005], g[5][100005];
vector<int> v[100005];
main() {
	freopen("a.in", "r", stdin);
	freopen("a.out", "w", stdout);
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin >> n >> m;
	int x, y;
	for (int i = 1; i <= m; i++) {
		cin >> x >> y;
		v[x].push_back(y);
		v[y].push_back(x);
	}
	for (int i = 1; i <= n; i++) {
		v[i].push_back(0);
		v[i].push_back(i);
		v[i].push_back(n + 1);
		sort(v[i].begin(), v[i].end());
		v[i].erase(unique(v[i].begin(), v[i].end()), v[i].end());
	}
	for (int i = 1; i <= n; i++) {
		f[1][i] = 1;
		g[1][i] = g[1][i - 1] + 1;
	}
	for (int i = 2; i <= 4; i++) {
		for (int j = 1; j <= n; j++) {
			for (int k = 1; k < v[j].size(); k++) {
				f[i][j] += (g[i - 1][v[j][k] - 1] - g[i - 1][v[j][k - 1]] + mod) % mod;
				f[i][j] = (f[i][j] + mod) % mod;
			}
		}
		for (int j = 1; j <= n; j++) {
			g[i][j] = g[i][j - 1] + f[i][j];
			g[i][j] = (g[i][j] + mod) % mod;
		}
	}
	long long ans = g[4][n] * g[4][n] % mod;
	long long sum = 0;
	for (int i = 1; i <= n; i++) {
		long long su = v[i].size() - 2;
		su = n - su;
		sum = (sum + f[3][i] * su % mod * su % mod + mod) % mod;
	}
	ans = ans * sum % mod;
	cout << ans;
	return 0;
}

铁路 60pts

赛时说不清的乱搞;

其实并不需要真的加点,只需要用并查集维护一下哪些点是被删掉的,然后把这个连通块连到这个新点即可;

好吧,其实原题解写的就这么简洁,所以我也不想写了

点击查看代码
#include <iostream>
#include <cstdio>
using namespace std;
int n, m;
struct sss{
	int t, ne;
}e[2000005];
int h[2000005], cnt;
void add(int u, int v) {
	e[++cnt].t = v;
	e[cnt].ne = h[u];
	h[u] = cnt;
}
int f[500005][25];
int fa[1000005], dep[1000005];
int id[1000005];
int find(int x) {
	if (x != fa[x]) fa[x] = find(fa[x]);
	return fa[x];
}
void dfs(int x, int faa) {
	f[x][0] = faa;
	dep[x] = dep[faa] + 1;
	for (int i = h[x]; i; i = e[i].ne) {
		int u = e[i].t;
		if (u == faa) continue;
		dfs(u, x);
	}
}
int ans;
int lca(int x, int y) {
	if (x == y) return x;
	if (dep[x] < dep[y]) swap(x, y);
	for (int i = 20; i >= 0; i--) {
		if (dep[f[x][i]] >= dep[y]) x = f[x][i];
	}
	if (x == y) return x;
	for (int i = 20; i >= 0; i--) {
		if (f[x][i] != f[y][i]) {
			x = f[x][i];
			y = f[y][i];
		}
	}
	return f[x][0];
}
void w(int x, int y, int now) {
	int sum = 0;
	x = id[x];
	y = id[y];
	int lc = find(lca(x, y));
	id[now] = lc;
	while(find(x) != lc) {
		fa[find(x)] = lc;
		x = find(f[x][0]);
		sum++;
	}
	while(find(y) != lc) {
		fa[find(y)] = lc;
		y = find(f[y][0]);
		sum++;
	}
	ans -= sum;
}
int main() {
	freopen("a.in", "r", stdin);
	freopen("a.out", "w", stdout);
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin >> n >> m;
	int x, y;
	for (int i = 1; i <= n - 1; i++) {
		cin >> x >> y;
		add(x, y);
		add(y, x);
	}
	for (int i = 1; i <= n + m; i++) {
		fa[i] = i;
		id[i] = i;
	}
	dfs(1, 0);
	for (int j = 1; j <= 20; j++) {
		for (int i = 1; i <= n; i++) {
			f[i][j] = f[f[i][j - 1]][j - 1];
		}
	}
	ans = n;
	for (int i = 1; i <= m; i++) {
		cin >> x >> y;
		w(x, y, n + i);
		cout << ans << '\n';
	}
	return 0;
}

To be continued...

标签:赛记,fa,int,sum,find,dep,include,csp,模拟
From: https://www.cnblogs.com/PeppaEvenPig/p/18427844

相关文章

  • 2024.8.21 模拟赛 26
    模拟赛怎么都找不到原题了?T1博弈trick,容易发现如果有一个数在路径上的出现次数为奇数,那么先手就能赢。问题是如何判断路径上是否有一个数出现奇数次。是一个存在性问题,考虑异或哈希,发现如果两个相同的数异或和为零,并且\(d_{u,v}=d_{root,u}\oplusd_{root,v}\)。如果......
  • 2024.8.19 模拟赛 24
    模拟赛总是忘记保存怎么办难得挂分。T1ANDandSUM签到题,如果两数按位与结果为\(a\),那么它们的二进制重复为\(1\)的位一定就是\(a\)的二进制为\(1\)的位置,所以它们相加的值至少是\(2a\)。并且不够的差值只能在\(a\)二进制为零的位置补(否则会有进位),所以判\((s-2a)......
  • 2024.8.18 模拟赛 22
    模拟赛T1先崩,然后电脑又崩。题面都在这里了T12-Coloring原题3100,张口放T1(这是原话)看起来像dp,推了两个小时大力分讨,最后式子比我命还长。刚推出来就发现假了正解差不多人类智慧吧,也可能只是小trick。对于整张图,考虑最终染色的“形状”。(下面这个样子)图片来自题解C......
  • CSP 集训记录
    用来整理模拟赛等9.23csp-3【noip23ZR二十连测DAY10】保龄.A.奇观狗市题目描述。不是这题意太大歧义了吧,我讨厌的第二种出题人——题意描述相当不清。CTH:13座城市又不代表是13座不同的城市。直接看形式化题目的话(如果能看懂要干什么)那这题确实不难。解:容易发......
  • 20240923 模拟赛总结
    期望得分:0+30+40+20=90实际得分:0+0+0+0=0爆了啊?!!!肚子不舒服晚了很久才开题……但开完题心就凉透了,一题不会啊!!!直接绷不住了。。T1一眼是树形DP,我、也想到了对于子树异或和为\(0,x\)去进行分析,结果感觉怎么都算不出来,看完题解才恍然大悟,原来可以从删除边数的奇偶性去进行DP......
  • 信息学奥赛复赛复习01-CSP-J2019-01-字符、字符数组、字符串、string、字符串读取
    信息学奥赛复赛复习01-CSP-J2019-01-字符、字符数组、字符串、string、字符串读取PDF文档公众号回复关键字:2024092312019CSP-J题目1数字游戏[题目描述]小K同学向小P同学发送了一个长度为8的01字符串来玩数字游戏,小P同学想要知道字符串中究竟有多少个1。注......
  • 《模拟火车世界5》游戏启动时崩溃弹窗“找不到msvbvm60.dll”文件该怎么修复?模拟火车
    在启动《模拟火车世界5》时,若遭遇崩溃并弹窗提示“找不到msvbvm60.dll”文件,可以从可靠渠道下载该文件,放置到系统指定目录。也可尝试重新安装游戏或使用系统修复工具来解决此问题。本篇将为大家带来《模拟火车世界5》游戏启动时崩溃弹窗“找不到msvbvm60.dll”文件该怎么修复的......
  • 『模拟赛』CSP-S模拟3
    因为正式集训所以不叫加赛了。RankUpd:非常好数据,掉分掉Rank。还行,其实是Rank6,其实其实是Rank4(丁真说正式比赛不会改数据。A.奇观简单题(?)。赛时琢磨了一会想到了\(Ans=C\cdotC\cdotF\),打出了\(m=0\)性质和\(O(n^2)\)dp的暴力一共80pts。赛后发现在我做法的......
  • CSP 初赛游寄
    前言时间是什么,一个定义还是具体的量,是否存在,令人捉摸不透,但不变的终有一点,一切都在变化啊,毕竟运动是绝对的\(CSP-J/S\),去年九月对于这个名词的理解,我还是一知半解。刚踏上信息竞赛的道路,不知道这意味着什么,转眼间,又一个九月,再次踏入一中的校门,看见新七年级与我们之前同样的期......
  • android 识别设备是否为模拟器
    一个识别工具类,android12-14测试有效,其他版本未测:publicclassEmulatorDetectionUtil{privatestaticfinalString[]PKG_NAMES={"com.mumu.launcher","com.ami.duosupdater.ui","com.ami.launchmetro","com.ami.syncduosservices",&qu......