# 【CSES】1617. Bit Strings ## [題目連結](https://cses.fi/problemset/task/1617) ## **時間複雜度** * $O(N)$ ## **解題想法** ### 位元運算的觀點 這題的話他是要輸出長度為 $N$ 的所有位元的排列,想不到的話可以觀察一下面的這張表 | Decimal | Binary | | ------- | ------ | | 0 | 0000 | | 1 | 0001 | | 2 | 0010 | | 3 | 0011 | | **4** | **0100** | | 5 | 0101 | | 6 | 0110 | | 7 | 0111 | | **8** | **1000** | | 9 | 1001 | | 10 | 1010 | 我們可以從表中發現,如果我們要算長度為 N 的所有排列的話,我們只需要將 1 右移 N 位,這樣就可以得到我們要的答案了 值得注意的有兩點: 1. 可以直接用 1 << N 的原因是我們也要將 0 算進去,同時又不要 1 << N 這一個位元,所以數量加一減一會剛好是我們要的答案 2. 這題是不能一次推到底的,要一個一個慢慢推同時一直取模,不然會有數字過大的問題 ### 次方的觀點 可以講這題看成每一個位元有 2 種可能性,所以要輸出的答案就是 $2^N$ 然後這邊也跟位元運算一樣,要慢慢乘上去並同時取模,否則答案會過大 ## **完整程式** ### 位元運算解 ```cpp= /* Question : CSES 1617. Bit Strings */ #include<bits/stdc++.h> using namespace std; #define opt ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0); #define mem(x) memset(x, 0x3F, sizeof(x)); #define pii pair<int, int> #define pdd pair<double, double> #define f first #define s second #define int long long const auto dir = vector< pair<int, int> > { {1, 0}, {0, 1}, {-1, 0}, {0, -1} }; const int MAXN = 1e8 + 50; const int Mod = 1e9 + 7; int n; signed main(){ opt; cin >> n; int ans = 1; for( int i = 0 ; i < n ; i++ ){ ans <<= 1; ans %= Mod; } cout << ans << "\n"; } ``` ### 一般解 ```cpp= /* Question : CSES 1617. Bit Strings */ #include<bits/stdc++.h> using namespace std; #define opt ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0); #define mem(x) memset(x, 0x3F, sizeof(x)); #define pii pair<int, int> #define pdd pair<double, double> #define f first #define s second #define int long long const auto dir = vector< pair<int, int> > { {1, 0}, {0, 1}, {-1, 0}, {0, -1} }; const int MAXN = 1e8 + 50; const int Mod = 1e9 + 7; int n; signed main(){ opt; cin >> n; int ans = 1; for( int i = 0 ; i < n ; i++ ){ ans *= 2; ans %= Mod; } cout << ans << "\n"; } ```