func_code_string: #include <bits/stdc++.h>   using namespace std;   const int MAXN = 1e5 + 100;   const int MAXT = 1e10 + 1000;   int N;   long long T;   const double EPS = 1e-12;   const double CHTLB = -1;   const double CHTUB = 1e20;   double V, t;   double pow(double b, long long p) {     assert(p >= 0);     if (p == 0) return 1;     if (p == 1) return b;     double r = static_cast<double>(1);     for (; p; p >>= 1, b *= b)       if (p & 1) r *= b;     return r;   }   long long rlog2(long long v) {     long long ret = 1;     while (v >>= 1) ret++;     return ret;   }   bool equ(const double& a, const double& b) { return abs(a - b) < EPS; }   bool Q;   double r[MAXN];   struct Line {    public:     Line() {       m = b = -1;       id = -1;     }     Line(const double& a, const double& c) {       m = a;       b = c;       id = -1;     }     Line(const long long& s) {       m = b = -1;       id = s;     }     Line(const double& a, const double& c, const int& s) { m = a, b = c, id = s; }     double m;     double b;     int id;     bool operator<(const Line& o) const {       if (!Q)         return o.m > m;       else         return r[o.id] > r[id];     }     double operator()(const double& x) const { return m * x + b; }     bool operator()(const double& x, const double& y) const {       return equ((*this)(x), y);     }     pair<double, double> operator*(const Line& o) const {       assert(!equ(m, o.m));       double x = (o.b - b) / (m - o.m);       double y = (o.b * m - b * o.m) / (m - o.m);       return make_pair(x, y);     }     bool keep(const Line& l, const Line& r) const {       return (l * *this).first < (*this * r).first;     }   };   struct CHT {    public:     multiset<Line> lines;     CHT() { Q = false; }     void pout() {       for (multiset<Line>::iterator it = lines.begin(); it != lines.end(); it++) {         cerr << it->m <<  x +   << it->b <<  (  << it->id <<  ) up to                << r[it->id] <<   n ;       }     }     bool insert(const Line& l) {       if (lines.empty()) {         r[l.id] = CHTUB;         lines.insert(l);         return true;       }       multiset<Line>::iterator c = lines.lower_bound(l);       if (c != lines.end()) {         if (equ(c->m, l.m)) {           if (l.b > c->b)             lines.erase(c);           else             return false;         }       }       c = lines.insert(l);       multiset<Line>::iterator p[2], n[2];       n[0] = c;       p[0] = c;       if (c != lines.begin() and ++n[0] != lines.end()) {         --p[0];         if (!c->keep(*p[0], *n[0])) {           lines.erase(c);           return false;         }       }       if (c == lines.begin()) {       } else {         p[0] = c, p[1] = --p[0];         while (p[0] != lines.begin()) {           p[1]--;           if (p[0]->keep(*p[1], *c)) {             break;           } else {             lines.erase(p[0]);             p[0] = p[1];           }         }         r[p[0]->id] = ((*p[0]) * (*c)).first;       }       n[0] = c, n[1] = ++n[0];       if (n[0] == lines.end()) {         r[c->id] = CHTUB;       } else {         while (++n[1] != lines.end()) {           if (n[0]->keep(*c, *n[1])) {             break;           } else {             lines.erase(n[0]);             n[0] = n[1];           }         }         r[c->id] = ((*n[0]) * (*c)).first;       }       return true;     }     double operator()(const double& x) const {       assert(CHTLB < x and x < CHTUB);       Q = true;       multiset<Line>::iterator c = lines.lower_bound(x);       Q = false;       assert(c != lines.end());       return (*c)(x);     }   } hull;   struct mat {    public:     vector<vector<double> > m;       private:     int L, W;     void fix() {       L = m.size();       W = m[0].size();     }       public:     void pout() {       fix();       for (int l = 0; l < L; l++) {         for (int w = 0; w < W; w++) {           cerr << m[l][w] <<    ;         }         cerr <<   n ;       }       cerr <<   n ;     }     mat(const int& l = 1, const int& w = 1) {       L = l, W = w;       vector<double> r(W, 0);       m = vector<vector<double> >(L, r);       if (l == w) {         for (int i = 0; i < l; i++) m[i][i] = 1;       }     }     vector<double>& operator[](const int& r) {       fix();       assert(0 <= r and r < L);       return m[r];     }     double& operator()(const int& r, const int& c) {       fix();       assert(0 <= r and r < L);       assert(0 <= c and c < W);       return m[r][c];     }     mat operator*(mat& o) {       fix();       o.fix();       assert(W == o.L);       mat ret(L, o.W);       for (int l = 0; l < L; l++) {         for (int c = 0; c < o.W; c++) {           ret[l][c] = 0;           for (int i = 0; i < W; i++) {             ret[l][c] += m[l][i] * o.m[i][c];           }         }       }       return ret;     }   };   int a[MAXN], b[MAXN];   double p[MAXN];   double dp;   long long ct;   mat st[500];   long long next(double p, double a, double cut) {     long long v = rlog2(T - ct);     st[0].m = {{static_cast<double>(1) - p, p * V, p * a}, {0, 1, 1}, {0, 0, 1}};     for (int i = 1; i <= v; i++) {       st[i] = st[i - 1] * st[i - 1];     }     mat cm(3, 3);     mat dpm(3, 1);     dpm.m = {{dp}, {static_cast<double>(ct)}, {1}};     long long dt = 0;     for (long long i = v; i >= 0; i--) {       if (ct + dt + (1LL << i) > T) continue;       mat cmt = cm * st[i];       if (V * (ct + dt + (1LL << i)) - (cmt * dpm)[0][0] > cut)         ;       else {         cm = cmt;         dt += (1LL << i);         assert(equ(static_cast<double>(dt), cm[1][2]));       }     }     mat rt = cm * dpm;     assert(equ(static_cast<double>(ct + dt), rt[1][0]));     if (dt + ct < T and V * (ct + dt) - rt[0][0] < cut) {       dt++;       rt = st[0] * rt;     }     dp = rt[0][0];     return dt + ct;   }   int main() {     Q = false;     cerr << setprecision(10);     scanf( %d%lld , &N, &T);     V = 0;     for (int i = 0; i < N; i++) {       scanf( %d%d%Lf , a + i, b + i, p + i);       if ((t = b[i] * p[i]) > V) V = t;     }     for (int i = 0; i < N; i++) {       hull.insert(Line(p[i], p[i] * a[i], i));     }     ct = 0;     dp = 0;     for (auto path : hull.lines) {       ct = next(p[path.id], a[path.id], r[path.id]);       assert(ct <= T);       if (ct == T) break;     }     printf( %.10Lg n , dp);     return 0;   }   