C++ 排除原则的实现

C++ 排除原则的实现,c++,algorithm,C++,Algorithm,我找到了一个用于解决问题的代码。我了解它的大部分内容,但我不明白排除原则是如何应用的,请帮助我理解它 问题 我有一个元素数组。每个元素都有一个高度Hi和一个颜色Ci。我必须找到元素序列的数量,它们严格地按高度增加,并且包含所有可能的列(从1到K) 我可以使用位算法找出递增序列的数量,但问题是如何满足第二个条件,即每个序列至少包含所有可用颜色的一个元素 示例:(第一列的高度和第二列的颜色) 两个有效的子序列是(1,2,4)和(1,3,4) 代码: int res=0; 对于(int mask=0;

我找到了一个用于解决问题的代码。我了解它的大部分内容,但我不明白排除原则是如何应用的,请帮助我理解它

问题 我有一个元素数组。每个元素都有一个高度Hi和一个颜色Ci。我必须找到元素序列的数量,它们严格地按高度增加,并且包含所有可能的列(从1到K)

我可以使用位算法找出递增序列的数量,但问题是如何满足第二个条件,即每个序列至少包含所有可用颜色的一个元素

示例:(第一列的高度和第二列的颜色)

两个有效的子序列是(1,2,4)和(1,3,4)

代码:

int res=0;
对于(int mask=0;mask<(1>(C[i]-1))&1){
dp[i]=1+查询(H[i]-1);//位查询函数
madd(tmp,dp[i]);
update(H[i],dp[i]);//位更新函数
}
}
如果(uuu内置_uupopcount(掩码)%2==K%2){
madd(res,tmp);
}否则{
madd(res,mod-tmp);
}
}

我不完全理解细节,但这里有一个大致的想法

考虑一组不同的、更简单的问题:

取现有颜色的一些适当子集1…K。 当您不允许使用此颜色子集(但没有义务使用任何颜色)时,您可以制作多少合法(根据高度)序列

要回答这些问题,可以很容易地使用BIT()


代码由一个范围为
0…2**K
(其中
2**K
计算为
1)的数字
mask
表示一个子集。请澄清您的问题。您到底需要什么帮助?(另请参见)@anatolyg您能帮助我或提供一些方向吗?您的链接已断开(需要订阅或类似链接);请描述您试图解决的问题(编辑您的问题并添加问题的描述)。我已编辑了问题;我希望我没有做任何根本性的更改,也没有删除有价值的数据。如果我做错了,请还原或更正。这不应过于宽泛,因为这里有一个特定的问题。即,“如何使用包含排除法只计算所有颜色的序列?”答案是,“颜色
(-1)**(size(S))*count(S中没有任何值的上升序列)
”的子集
S
的和在数学论坛上可能更好,尽管大多数程序员不理解包含排除法。
4 3
1 1
3 2
2 2
4 3
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);
    }
  }