这题的关键就是推出有且仅有 1个、2个、3个三种情况。然后枚举+二分即可。话说通过这题竟然意外弥补了自己二分上的一个小缺陷~(ps:果然,应该再睡一会再来补题的,凌晨打完现在补题,我都不知道我敲得是什么鬼)
证明:不妨先对序列排个序,那么对于数x,它的下一个数一定是x+2^d,在第一个数是x,第二个数是x+2^d的情况下,第三个数只能是x+2*2^d,因为首先第三个数要比第一个数大2的幂次倍,所以它等于 x + 2^k,又因为还要和第二个数满足条件,所以他们的差必须是2的幂次,做减法:(2^y - 1) * 2^d,其中y+d = k,而可以使(2^y - 1) 为2的幂次的取值有且仅有1,即 其取值为 x + 2 * 2 ^ d,命题得证。
#include <bits/stdc++.h> using namespace std; typedef long long ll; ll a[200200]; ll f(ll d){ ll ans = 1; for(ll i = 0; i < d; i ++) ans *= 2; return ans; } int main(){ ll n; cin >> n; for(ll i = 0; i < n; i ++) cin >> a[i]; sort(a, a + n); ll d; vector <ll> ans; for(ll i = 0; i < n; i ++){ for(ll j = 0; a[i] + f(j) <= a[n - 1]; j ++){ //又写出一个bug vector <ll> temp; ll t1 = a[i] + f(j); ll t2 = a[i] + 2 * f(j); ll ul = i, ur = n - 1; //注意二分的边界,左开右闭,妙处无限 while(ur - ul > 1){ ll mid = (ul + ur) / 2; if(a[mid] >= t1) ur = mid; else ul = mid; } if(a[ur] == t1){ temp. push_back(a[i]); temp. push_back(t1); ul = ur, ur = n - 1; while(ur - ul > 1){ ll mid = (ul + ur) / 2; if(a[mid] >= t2) ur = mid; else ul = mid; } if(a[ur] == t2){ temp. push_back(t2); } } if(temp. size() > ans. size()){ ans. clear(); for(int i = 0; i < temp. size(); i ++) ans. push_back(temp[i]); } } } if(ans. size() == 0) //没仔细读题搞出来的bug ans. push_back(a[0]); cout << ans. size() << endl; for(int i = 0; i < ans. size() - 1; i ++) cout << ans[i] << ' '; cout << ans[ans. size() - 1] << endl; return 0; }