组合数学+逆元
http://oj.jxust.edu.cn/contest/Problem?id=1702&pid=6
题意:有n个人,现在有一个聚会,每个人都可以选择参加或者不参加。而参加的人中每个人要么只去送礼物,要么只接受礼物。不存在全部都接受礼物或者全部都送礼物的情况(这样要么没人送礼物,要么没人接受礼物了)。问有多少中情况?
输出:对结果mod1e9+7.
解法:ans=∑C(k,n)*(2^k-2)其中2<=k<=n
//#include <bits/stdc++.h> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <iostream> #include <algorithm> #include <iostream> #include <cstdio> #include <string> #include <cstring> #include <stdio.h> #include <queue> #include <stack>; #include <map> #include <set> #include <ctype.h> #include <string.h> #include <vector> #define ME(x , y) memset(x , y , sizeof(x)) #define SF(n) scanf("%d" , &n) #define rep(i , n) for(int i = 0 ; i < n ; i ++) #define INF 0x3f3f3f3f #define PI acos(-1) using namespace std; typedef long long ll ; const int mod = 1e9+7 ; ll quickpow(ll x , ll y) { ll ans = 1 ; while(y) { if(y & 1) ans = (ans * x) % mod ; y >>= 1 ; x = (x * x) % mod; } return ans % mod ; } int main() { int n ; scanf("%d" , &n); if(n == 1) { cout << 1 << endl ; return 0 ; } if(n == 2) { cout << 2 << endl ; return 0 ; } ll x = n , y = 1 , ans = 0 ; for(int i = 2 ; i <= n ; i++) { x = (x * (n - i + 1))% mod , y = y * i % mod ; ans = (ans + x * quickpow(y , mod - 2)%mod * (quickpow(2 , i) - 2)) % mod; } cout << ans << endl ; return 0; }
求两数组
//#include <bits/stdc++.h> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <iostream> #include <algorithm> #include <iostream> #include <cstdio> #include <string> #include <cstring> #include <stdio.h> #include <queue> #include <stack>; #include <map> #include <set> #include <ctype.h> #include <string.h> #include <vector> #define ME(x , y) memset(x , y , sizeof(x)) #define SF(n) scanf("%d" , &n) #define rep(i , n) for(int i = 0 ; i < n ; i ++) #define INF 0x3f3f3f3f #define PI acos(-1) using namespace std; typedef long long ll ; const int mod = 1e9+7 ; ll a[100009] , m[100009]; ll quickpow(ll x , ll y) { ll ans = 1 ; while(y) { if(y & 1) ans = (ans * x) % mod ; y >>= 1 ; x = (x * x) % mod; } return ans % mod ; } int main() { int n ; scanf("%d" , &n); if(n == 1) { cout << 1 << endl ; return 0 ; } if(n == 2) { cout << 2 << endl ; return 0 ; } a[1] = 1 , m[0] = 1 ; for(int i = 2 ; i <= n ; i++) { a[i] = a[i-1] * i % mod ; } m[n] = quickpow(a[n],mod-2); for(int i = n - 1 ; i >= 1 ; i--)//可以将逆元看成是倒数求解。 { m[i] = m[i+1] * (i+1) % mod ; } ll ans = 0 ; for(int i = 2 ; i <= n ; i++) { ans += a[n]%mod * m[i]%mod * m[n-i]%mod * (quickpow(2 , i)-2)%mod; ans %= mod ; } cout << ans << endl; return 0; }