ABC 304

T4

在一个平面上有一块面积无限的蛋糕,给出 \(n\) 颗草莓的所在位置和 \(a\,(b)\) 条平行与 \(x\,(y)\) 轴的切刀位置。

切刀会把蛋糕沿 \(x\,(y)\) 轴切开。因此一共会切出 \((a+1)(b+1)\) 块蛋糕。

问:现在蛋糕上草莓数量最少的一块蛋糕,草莓数量是多少?最多的,又是多少?


用 lower_bound 计算出每一个草莓所属的行数和列数,然后用 map 维护草莓所在的块的草莓数量。

最小:如果有一块区域没有草莓,就是 0;否则在用 map 维护的时候就已经可以得出答案了。

T5

给出一张图和一些点对 \((x_i,y_i)\)

定义好图:每对 \((x_i,y_i)\),都不存在路径到达。

再给出一些询问 \((p,q)\),表示询问加上 \((p,q)\) 这条边后,图是否依然是好图。


考虑每对 \((x,y)\) 和每对 \((p,q)\) 所在的连通块。

给每个连通块一个编号,记 \(id[u]\)\(u\) 所在的连通块编号。

只有满足 \((id[p],id[q])\) 和每对 \((id[x],id[y])\) 都不相同,图才能依然保持为好图。

T6

\(n\) 天,给出一个长度为 \(n\) 的字符串 \(s\),表示小 A 的工作表,若为 # 则表示工作,反之为 . 则表示休息。

接下来,小 B 要决定他的工作表 \(t\)(也是 #.),对于一个 \(m\) 满足 \(m|n\),决定他的前 \(m\) 天的工作表,然后让第 \(i+m\) 天的工作情况和第 \(i\) 天一样,并且要求 \(n\) 天中每一天小 A 和小 B 都有至少一人工作,问共有多少种工作表的方案。


先枚举 \(m\)\(n\) 的因数,\(O(\sqrt n)\),然后枚举 \(s\)每一个字符。如果 \(s[i]\).,则 \(t[i\mod m]\) 必须为 #

假设 \(t\)\(m\) 个字符中还剩下 \(k\) 个可以为 . 的位置,这些位置可以随便选,有 \(2^k\) 中。

但是,还要减去重复的情况:当 \(m=8\)#.#.#.#.,可以在 \(m=4\)#.#. 算一次。但又不能简单的减去,因为还有 \(m=2\)#.……

所以做个容斥。

int dfs(string s) //求出s中有多少重复的情况 
{
	int ans = 0;
	for (int i = 1; i <= cnt; ++i) {
		if (s.length() % a[i] != 0 || a[i] == s.length()) continue;
		string t = "";
		int x = 0;
		for (int j = 0; j < a[i]; ++j) t += '.';
		for (int j = 0; j < s.length(); ++j)
			if (s[j] == '#') t[j % a[i]] = '#';
		for (int j = 0; j < t.length(); ++j)
			if (t[j] == '.') ++x;
		ans = ((ans + qpow(2, x, mod) - dfs(t)) % mod + mod) % mod;
	}
	return ans;
}
int solve(string s) //求出基于s的t有多少方案 
{
	int ans = 0;
	for (int i = 1; i <= cnt; ++i) {
		if (s.length() % a[i] != 0 || a[i] == s.length()) continue;
		string t = "";
		int x = 0;
		for (int j = 0; j < a[i]; ++j) t += '.';
		for (int j = 0; j < s.length(); ++j)
			if (s[j] == '.') t[j % a[i]] = '#';
		for (int j = 0; j < t.length(); ++j)
			if (t[j] == '.') ++x;
		ans = ((ans + qpow(2, x, mod) - dfs(t)) % mod + mod) % mod;
	}
	return ans;
}
posted @ 2024-02-08 18:38  FLY_lai  阅读(3)  评论(0编辑  收藏  举报