题意:
给一集合 $S = { 1,2, ... , n } $,取两个S的子集 A和B,使得A不是B的子集,且B不是A的子集。
解法:
1.牛顿展开
我们采用容斥,显然有
$$ans(n) = (2^n - 1)^2 - 2* sum_{k=1}^n{C_n^k * (2^k - 2)} - (2^n-1)$$
$$ans(n) = (2^n - 1)(2^n-2) - 2*(sum_{k=1}^n{C_n^k *2^k} - 2*sum_{k=1}^n{C_n^k})$$
$$ans(n) = 4^n - 2*3^n + 2^n$$
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <complex> 5 #include <cmath> 6 #include <ctime> 7 8 using namespace std; 9 10 #define N 1000010 11 #define LL long long 12 #define P 1000000007LL 13 14 using namespace std; 15 16 LL power3[N],power2[N]; 17 18 int main() 19 { 20 power3[0]=1; 21 power2[0]=1; 22 for(int i=1;i<N;i++) 23 { 24 power3[i] = power3[i-1] * 3LL % P; 25 power2[i] = power2[i-1] * 2LL % P; 26 } 27 int T,n; 28 scanf("%d",&T); 29 while(T--) 30 { 31 scanf("%d",&n); 32 LL ans = power2[n]*(power2[n]+1LL)%P; 33 ans = (ans+P-2LL*power3[n]%P)%P; 34 printf("%I64d ",ans); 35 } 36 return 0; 37 }
2.生成函数(待补)
可以构造出