/*
P20页:难度增加的抽签问题
核心:处理大数据时,二分查找算法lgn的时间复杂度是很省时间的
问题:n个签,有放回抽取4次,求和是否有可能为m,n<1000
解决:1。四次循环得到4只签求和后和m比较,时间复杂度为n^4,12个0,不行
2。三次循环后得到三支签k1,k2,k3,然后二分查找最后一只签m-k1-k2-k3,找到则返回ture,否则返回false,时间为n^3lgn,10个0,不行
3。二次循环后得到二只签k1, k2,枚举2只签的和的n^2种情况并排序,然后再其中二分查找n-k1-k2。排序的时间复杂度为n^2lgn^2=2n^2lgn=o(n^2lgn),二次循环加二分查找的时间复杂度为o(n^2lgn^2),总的时间复杂度为n^2lgn, 7个0,可以轻松运行处结果
*/
#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
using namespace std;
const int Max = 1010;
int n, m;
int k[Max];
int main(void)
{
int k_enum[2*Max];
int it0 = 0;
cin >> n >> m;
for (int i = 0; i < n; i++)
cin >> k[i];
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
{
k_enum[it0] = k[i] + k[j];
it0++;
}
sort(k_enum, k_enum + n * n);
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
{
if( binary_search(k_enum, k_enum+n*n, m-k[i]-k[j]) )
{
cout << "Yes";
return 0;
}
}
cout << "No";
return 0;
}