ABC 458 球盒模型|AC自动机|矩阵快速幂DP

D

对顶堆模板

题意

每次增加两个元素,问中位数,保证集合大小一直是奇数

分析

动态求中位数,直接对顶堆。pypypy的话sortedlist也可以,可惜cppcppcpp没有这种方便的库

c 复制代码
struct Set {
	const int kInf = 1e9 + 2077;
	std::multiset<int> less, greater;
	void init() {
		less.clear(), greater.clear();
		less.insert(-kInf), greater.insert(kInf);
	}
	void adjust() {
		while (less.size() > greater.size() + 1) {
			std::multiset<int>::iterator it = (--less.end());
			greater.insert(*it);
			less.erase(it);
		}
		while (greater.size() > less.size()) {
			std::multiset<int>::iterator it = greater.begin();
			less.insert(*it);
			greater.erase(it);
		}
	}
	void add(int val_) {
		if (val_ <= *greater.begin())
			less.insert(val_);
		else
			greater.insert(val_);
		adjust();
	}
	void del(int val_) {
		std::multiset<int>::iterator it = less.lower_bound(val_);
		if (it != less.end()) {
			less.erase(it);
		} else {
			it = greater.lower_bound(val_);
			greater.erase(it);
		}
		adjust();
	}
	int get_middle() {
		return *less.rbegin();
	}
};
void solve() {
	int x, q;
	cin >> x >> q;

	Set s;
	s.init();
	s.add(x);
	rep(i, 1, q) {
		int a, b;
		cin >> a >> b;
		s.add(a);
		s.add(b);
		cout << s.get_middle() << '\n';
	}
}

E

组合数学 隔板法

题意

1,2,31,2,31,2,3分别x1,x2,x3x_1,x_2,x_3x1,x2,x3个,组成一个序列,要求相邻元素差的绝对值不超过111。问有多少个不同序列?

分析

注意到不满足这个要求的只有1,31,31,3直接相邻,所以可以把222当成隔板,吧1,31,31,3隔开。有x2x_2x2个222,则划分出x2+1x_2+1x2+1个区域,每个区域里要么空,要么全是111,要么全是333

那么枚举x1x_1x1有iii段,从x2+1x_2+1x2+1个位置里选iii段给111,方案数C(x1+1,i)C(x_1+1,i)C(x1+1,i),把x1x_1x1个111放进iii个位置里,不妨设不允许空位,这是经典球盒问题,方案数C(x1−1,i−1)C(x_1-1,i-1)C(x1−1,i−1),剩下的x2+1−ix_2+1-ix2+1−i位置拿来放x3x_3x3个333,允许空盒,方案数C(x2+1−i+x3−1,x3)C(x_2+1-i+x_3-1,x_3)C(x2+1−i+x3−1,x3)

实现

c 复制代码
void solve() {
	int x, y, z;
	cin >> x >> y >> z;
	int ans = 0;

	int box = y + 1;
	rep(i, 1, x) {
		ans += C(y + 1, i) * C(x - 1, i - 1) % M2 * C(box - i + z - 1, z) % M2;
		ans %= M2;
	}
	cout << ans;


}

F

AC 自动机 矩阵快速幂优化DPDPDP

题意

和给101010个串,长度不超过101010,问长度为1e91e91e9的,不含这些串作为子串的串个数?

分析

模式串不能出现,问合法串数,这可以KMPKMPKMP思想,维护模式串匹配到哪了,如果完成了一个完整的模式串匹配,那么从这个状态开始,接下来到的状态,都标记为非法。

这样我们构建了一个自动机,上面一些节点是非法的。把非法节点删掉,得到的子图是一个只接受合法串的自动机。求走nnn步的方案数,在这个自动机上从初态开始,转移nnn次,每个点保存到达这个状态的方案数,然后对所有状态方案数求和。

这里有多个模式串的话,KMPKMPKMP拓展到ACACAC自动机即可。先ACACAC自动机建出来,然后把这个自动机对应的图写成一个邻接矩阵的形式,求n=1e9n=1e9n=1e9步的结果,对这个矩阵做矩阵快速幂即可。

c 复制代码
struct Aho_Corasick_Automaton {
	queue<int> q;
	int c[N][26], val[N], fail[N], cnt;

	void init() {
		memset(c, 0, sizeof(c));
		memset(val, 0, sizeof(val));
		memset(fail, 0, sizeof(fail));
		cnt = 0;
	}

	void ins(string &s) {
		int len = s.size();
		int now = 0;
		for (int i = 0; i < len; i++) {
			int v = s[i] - 'a';
			if (!c[now][v]) c[now][v] = ++cnt;
			now = c[now][v];
		}
		val[now]++;
	}

	void build() {
		for (int i = 0; i < 26; i++) if (c[0][i]) fail[c[0][i]] = 0, q.push(c[0][i]);
		while (!q.empty()) {
			int u = q.front();
			q.pop();

			val[u] |= val[fail[u]];

			for (int i = 0; i < 26; i++)
				if (c[u][i]) fail[c[u][i]] = c[fail[u]][i], q.push(c[u][i]);
				else c[u][i] = c[fail[u]][i];
		}
	}
} AC;


typedef vector<vector<long long>> Matrix;

// 矩阵乘法
Matrix multiply(const Matrix &A, const Matrix &B, long long MOD) {
	int n = A.size();
	int m = B[0].size();
	int k = B.size();
	Matrix C(n, vector<long long>(m, 0));

	for (int i = 0; i < n; ++i) {
		for (int j = 0; j < m; ++j) {
			for (int l = 0; l < k; ++l) {
				C[i][j] = (C[i][j] + A[i][l] * B[l][j] % MOD) % MOD;
			}
		}
	}
	return C;
}

// 矩阵快速幂
Matrix power(Matrix A, long long p, long long MOD) {
	int n = A.size();
	Matrix result(n, vector<long long>(n, 0));

	// 初始化结果矩阵为单位矩阵
	for (int i = 0; i < n; ++i) {
		result[i][i] = 1;
	}

	while (p) {
		if (p % 2 == 1) {
			result = multiply(result, A, MOD);
		}
		A = multiply(A, A, MOD);
		p /= 2;
	}

	return result;
}
void solve() {
	int n, k;
	cin >> n >> k;

	AC.init();
	rep(i, 1, k) {
		string s;
		cin >> s;
		AC.ins(s);
	}

	AC.build();

	int tot = AC.cnt + 1;

	Matrix f(tot, vi(tot));
	rep(i, 0, tot - 1) {
		if (AC.val[i])continue;
		rep(j, 0, 25) {
			int nxt = AC.c[i][j];
			if (!AC.val[nxt]) {
				f[i][nxt]++;
			}
		}
	}

	f = power(f, n, M2);
	int ans = 0;
	rep(i, 0, tot - 1) {
		if (!AC.val[i]) {
			ans = (ans + f[0][i]) % M2;
		}
	}
	cout << ans;
}
相关推荐
-dzk-18 小时前
【矩阵】LC 48.旋转图像
线性代数·矩阵
薛定e的猫咪21 小时前
(NeurIPS 2021)MatNet:面向矩阵型关系数据的神经组合优化编码器
人工智能·深度学习·线性代数·算法·矩阵
inquisiter2 天前
损失函数在标量和矩阵上的求导对比
线性代数·算法·矩阵
-dzk-2 天前
【矩阵】LC 54.螺旋矩阵
线性代数·矩阵
东莞市云毅网络有限公司3 天前
基于GEO的品牌信源矩阵构建:从内容生产到AI采信的全链路设计
人工智能·机器学习·矩阵
风吹心凉3 天前
错误码矩阵 · 实机兼容映射 · 契约变更规则
线性代数·矩阵
搭贝3 天前
国资报送责任制怎么建?三级责任矩阵设计
android·数据库·人工智能·线性代数·低代码·矩阵·制造
xier_ran3 天前
【infra之路】AWQ 详解:激活感知权重保护,让 W4A16 量化精度超越 GPTQ
线性代数·算法·机器学习·量化·infra
远航计算机4 天前
GEO自诊断实操手册:你的内容为什么AI搜不到?
人工智能·矩阵·aigc·媒体
晓晓_za8986684 天前
Geo 优化源码二次开发:自定义地域规则改造实操文档
java·开发语言·搜索引擎·ci/cd·矩阵