#include "bits/stdc++.h"
using namespace std;
#define all(x) x.begin(),x.end()
template<typename A, typename B> ostream& operator<<(ostream &os, const pair<A, B> &p) { return os << p.first << " " << p.second; }
template<typename T_container, typename T = typename enable_if<!is_same<T_container, string>::value, typename T_container::value_type>::type> ostream& operator<<(ostream &os, const T_container &v) { string sep; for (const T &x : v) os << sep << x, sep = " "; return os; }
#ifdef LOCAL
#include "debug.h"
#else
#define debug(...) 42
#define ASSERT(...) 42
#endif
typedef long long ll;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef pair<int,int> pi;
const int oo = 1e9;
typedef complex<double> C;
typedef vector<double> vd;
#define rep(i,a,b) for(int i=a;i<b;++i)
#define sz(x) int(x.size())
void fft(vector<C>& a) {
int n = sz(a), L = 31 - __builtin_clz(n);
static vector<complex<long double>> R(2, 1);
static vector<C> rt(2, 1); // (^ 10% faster if double)
for (static int k = 2; k < n; k *= 2) {
R.resize(n); rt.resize(n);
auto x = polar(1.0L, acos(-1.0L) / k);
rep(i,k,2*k) rt[i] = R[i] = i&1 ? R[i/2] * x : R[i/2];
}
vi rev(n);
rep(i,0,n) rev[i] = (rev[i / 2] | (i & 1) << L) / 2;
rep(i,0,n) if (i < rev[i]) swap(a[i], a[rev[i]]);
for (int k = 1; k < n; k *= 2)
for (int i = 0; i < n; i += 2 * k) rep(j,0,k) {
// C z = rt[j+k] * a[i+j+k]; // (25% faster if hand-rolled) /// include-line
auto x = (double *)&rt[j+k], y = (double *)&a[i+j+k]; /// exclude-line
C z(x[0]*y[0] - x[1]*y[1], x[0]*y[1] + x[1]*y[0]); /// exclude-line
a[i + j + k] = a[i + j] - z;
a[i + j] += z;
}
}
vd conv(const vd& a, const vd& b) {
if (a.empty() || b.empty()) return {};
vd res(sz(a) + sz(b) - 1);
int L = 32 - __builtin_clz(sz(res)), n = 1 << L;
vector<C> in(n), out(n);
copy(all(a), begin(in));
rep(i,0,sz(b)) in[i].imag(b[i]);
fft(in);
for (C& x : in) x *= x;
rep(i,0,n) out[i] = in[-i & (n - 1)] - conj(in[i]);
fft(out);
rep(i,0,sz(res)) res[i] = imag(out[i]) / (4 * n);
return res;
}
struct poly {
int off;
vd a;
double& operator[](int i) {return a[i-off];}
poly window(int l, int r) const {
l=max(l,off);
return {l, vd(a.begin()+(l-off),a.begin()+(r-off))};
}
poly operator*(const poly& o) const {
return {off,conv(a,o.a)};
}
};
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int n,t; cin >> n >> t;
vector<double> p(n);
for(auto& i: p) cin >> i;
sort(p.rbegin(),p.rend());
poly po = {0,vd(n+1,1)};
po.a[0]=0;
auto want = [&](int i) {
return (i+1+t+1)/2;
};
vd f(n);
auto rec = [&](auto&& self, int l, int r, poly cur) -> poly { // returns the normal product!
if(r-l==1) {
poly my = {0, {1-p[l],p[l]}};
auto res = cur*my;
f[l] = 1-res[want(l)];
return my;
}
int mid = (l+r)/2;
auto lhs = self(self,l,mid,cur.window(want(l)-(mid-l),want(mid-1)+1));
cur = cur*lhs;
auto rhs = self(self,mid,r,cur.window(want(mid)-(r-mid),want(r-1)+1));
return lhs*rhs;
};
rec(rec,0,n,po);
cout << setprecision(10) << fixed << *max_element(all(f)) << '\n';
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | #include "bits/stdc++.h" using namespace std; #define all(x) x.begin(),x.end() template<typename A, typename B> ostream& operator<<(ostream &os, const pair<A, B> &p) { return os << p.first << " " << p.second; } template<typename T_container, typename T = typename enable_if<!is_same<T_container, string>::value, typename T_container::value_type>::type> ostream& operator<<(ostream &os, const T_container &v) { string sep; for (const T &x : v) os << sep << x, sep = " "; return os; } #ifdef LOCAL #include "debug.h" #else #define debug(...) 42 #define ASSERT(...) 42 #endif typedef long long ll; typedef vector<int> vi; typedef vector<vi> vvi; typedef pair<int,int> pi; const int oo = 1e9; typedef complex<double> C; typedef vector<double> vd; #define rep(i,a,b) for(int i=a;i<b;++i) #define sz(x) int(x.size()) void fft(vector<C>& a) { int n = sz(a), L = 31 - __builtin_clz(n); static vector<complex<long double>> R(2, 1); static vector<C> rt(2, 1); // (^ 10% faster if double) for (static int k = 2; k < n; k *= 2) { R.resize(n); rt.resize(n); auto x = polar(1.0L, acos(-1.0L) / k); rep(i,k,2*k) rt[i] = R[i] = i&1 ? R[i/2] * x : R[i/2]; } vi rev(n); rep(i,0,n) rev[i] = (rev[i / 2] | (i & 1) << L) / 2; rep(i,0,n) if (i < rev[i]) swap(a[i], a[rev[i]]); for (int k = 1; k < n; k *= 2) for (int i = 0; i < n; i += 2 * k) rep(j,0,k) { // C z = rt[j+k] * a[i+j+k]; // (25% faster if hand-rolled) /// include-line auto x = (double *)&rt[j+k], y = (double *)&a[i+j+k]; /// exclude-line C z(x[0]*y[0] - x[1]*y[1], x[0]*y[1] + x[1]*y[0]); /// exclude-line a[i + j + k] = a[i + j] - z; a[i + j] += z; } } vd conv(const vd& a, const vd& b) { if (a.empty() || b.empty()) return {}; vd res(sz(a) + sz(b) - 1); int L = 32 - __builtin_clz(sz(res)), n = 1 << L; vector<C> in(n), out(n); copy(all(a), begin(in)); rep(i,0,sz(b)) in[i].imag(b[i]); fft(in); for (C& x : in) x *= x; rep(i,0,n) out[i] = in[-i & (n - 1)] - conj(in[i]); fft(out); rep(i,0,sz(res)) res[i] = imag(out[i]) / (4 * n); return res; } struct poly { int off; vd a; double& operator[](int i) {return a[i-off];} poly window(int l, int r) const { l=max(l,off); return {l, vd(a.begin()+(l-off),a.begin()+(r-off))}; } poly operator*(const poly& o) const { return {off,conv(a,o.a)}; } }; int main() { ios_base::sync_with_stdio(false); cin.tie(NULL); int n,t; cin >> n >> t; vector<double> p(n); for(auto& i: p) cin >> i; sort(p.rbegin(),p.rend()); poly po = {0,vd(n+1,1)}; po.a[0]=0; auto want = [&](int i) { return (i+1+t+1)/2; }; vd f(n); auto rec = [&](auto&& self, int l, int r, poly cur) -> poly { // returns the normal product! if(r-l==1) { poly my = {0, {1-p[l],p[l]}}; auto res = cur*my; f[l] = 1-res[want(l)]; return my; } int mid = (l+r)/2; auto lhs = self(self,l,mid,cur.window(want(l)-(mid-l),want(mid-1)+1)); cur = cur*lhs; auto rhs = self(self,mid,r,cur.window(want(mid)-(r-mid),want(r-1)+1)); return lhs*rhs; }; rec(rec,0,n,po); cout << setprecision(10) << fixed << *max_element(all(f)) << '\n'; } |
English