1. 程式人生 > >[C++]bitset特殊用法

[C++]bitset特殊用法

bitset特殊用法

本文我們介紹一個用bitset來解決特殊的問題。

問題產生

Give you N numbers a[1]…a[n]
and M numbers b[1]…b[m]
For each b[k], if we can find i,j  a[i] + a[j] = b[k] or a[i] = b[k] , we say k is a good number.
And you should only output the number of good numbers.
0 < n, m, a[i], b[j] <= 200000 
sample input
3 6
1
3
5
2
4
5
7
8
9
sample output
 4
 
 
b[1]…b[m]   2,4,5,7,8,9
2 = 1+1
4 = 1+3
5 = 5
8 = 3+5

問題分析

這題乍看起來是比較簡單的,可能最開始會嘗試用列舉所有的情況,但這樣的複雜度是O(n*m),必然會超時,特別是對於十萬級資料時,所以我們必須嘗試使用一種更為快捷的方式。

這裡我們使用bitset來完成問題。把a中所有的值都作為position定為在bitset裡面,然後對這個bitset進行移位操作,最後就可以快速地得到所有可能的情況。

演算法思路

利用bitset的非標準做法。利用bitset記錄哪些數在a中出現過了。那麼把這個bitset左移1位,我們就可以得到有哪些x(x=a[i]+1)出現過了。左移兩位,就知道哪些x(x = a[i]+2)出現過。如果此處左移a[1]那麼,得到的就是a[1]+a[1] ,… ,a[1]+a[n]這些數字的bitset。列舉a[1]到a[n]來左移,把結果取或,就能得到a[i]+a[j]的集合,再或上a[1]..a[n]的bitset,把這個結果和b[1]..b[m]的bitset取&, 剩下的這個bitset有多少個1,答案就是幾。

問題解決

#include <iostream>
#include <bitset>
#include <vector>
#define MAX_ELE 200000
using namespace std;
int main() {
    int n, m;
    cin >> n >> m;
    bitset<MAX_ELE> a;
    bitset<MAX_ELE> b;
    int pos;
    vector<int> temp;
    temp.reserve(MAX_ELE);
    while
(n--) { cin >> pos; temp.push_back(pos); a.set(pos); } while (m--) { cin >> pos; b.set(pos); } bitset<MAX_ELE> T_a = a; for (int i = 0; i != temp.size(); i++) { a = a | (T_a << temp[i]); } b = b & a; cout << b.count() << endl; }