我找到了一个使用exclusion_principle来解决Problem的代码。我理解其中的大部分内容但我无法理解如何应用排除原则,请帮助我理解。
问题 我有一系列元素。每个元素具有高度Hi和颜色Ci。我必须找到元素序列的数量,它们严格按高度增加并包含所有可能的colurs(从1到K)。
我可以通过使用BIT算法找出增加序列的数量,但问题是如何填充第二个条件,即每个序列包含所有可用颜色中的至少一个元素。
示例:(第一列中的高度和第二列中的颜色)
4 3
1 1
3 2
2 2
4 3
两个有效的子序列是(1,2,4)和(1,3,4)
代码:
int res = 0;
for(int mask = 0; mask < (1 << K); mask ++){
memset(ft, 0, sizeof ft);
int tmp = 0;
for(int i = 0; i < N; i++){
if((mask >> (C[i] - 1)) & 1){
dp[i] = 1 + query(H[i] - 1); // BIT Query function
madd(tmp, dp[i]);
update(H[i], dp[i]); // BIT update function
}
}
if(__builtin_popcount(mask) % 2 == K % 2){
madd(res, tmp);
} else {
madd(res, mod - tmp);
}
}
答案 0 :(得分:0)
我不完全了解细节,但这是一个大致的想法。
考虑一系列不同的,更简单的问题:
取一些适当的现有颜色子集1 ... K. 当你不被允许使用这个颜色子集(但没有义务使用任何颜色)时,可以制作多少合法(根据高度)序列?
要回答这些问题,它很容易使用BIT(binary indexed tree)。
代码表示mask
范围内的数字0...2**K
的子集(其中2**K
计算为1 << K
; 0表示完整的颜色集,因此它不应该使用,但见下文)。
要回答原始问题,您必须迭代所有颜色子集,并对结果应用inclusion-exclusion principle。每个单独的结果测量不包含某些颜色的所有序列的集合。因此,所有这些集合的确定恰好具有不包含某种颜色的元素序列。原始问题的答案是这一组的补充。
代码计算完整序列集的大小以及所有其他计算;从概念上讲,它并不属于那里,但在同一循环中计算它是很自然的。