Count Subsets

题意:

给一集合 $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$$

 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\n",ans);
35     }
36     return 0;
37 }
View Code

 

 

2.生成函数(待补)

可以构造出

posted @ 2017-03-06 17:47  lawyer'  阅读(119)  评论(0)    收藏  举报