mr_dot_convict

787-Maximum_sub_sequence_product-UVa-mr.convict

Jun 20th, 2019
160
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 13.95 KB | None | 0 0
  1. /*author* Priyanshu Shrivastav (from IIT Palakkad) *
  2.  * *_ __ ___  _ ______ ___  _ ____   ___  ___| |_  *
  3.  * | '_ ` _ \| '__/ __/ _ \| '_ \ \ / / |/ __| __| *
  4.  * | | | | | | | | (_| (_) | | | \ V /| | (__| |_  *
  5.  * |_| |_| |_|_|(_)___\___/|_| |_|\_/ |_|\___|\__| *
  6. When I wrote this, only God and I understood what I was doing
  7.  ** * * * * * * * Now, only God knows * * * * * * */
  8. #include         <bits/stdc++.h>
  9. using namespace std;
  10. #pragma GCC      optimize ("Ofast")
  11. #pragma GCC      optimize ("unroll-loops")
  12. #pragma GCC      target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
  13.  
  14. #define IOS      ios_base::sync_with_stdio(false); cin.tie (nullptr)
  15. #define PREC     cout.precision (10); cout << fixed
  16. #define bg(x)    " [ " << #x << " : " << (x) << " ]"
  17. #define x        first
  18. #define y        second
  19. using ll = long long;
  20.  
  21. #define debug(args...) { \
  22.    string _s = #args; replace(_s.begin(), _s.end(), ',', ' ');\
  23.    stringstream _ss(_s); istream_iterator<string> _it(_ss); err(_it, args); \
  24. }
  25. void err(istream_iterator<string> it) { it->empty();
  26.    cerr << " (Line : " << __LINE__ << ")" << '\n';
  27. }
  28. template<typename T, typename... Args>
  29. void err(istream_iterator<string> it, T a, Args... args) {
  30.     cerr << " [ " <<  *it << " : " << a  << " ] "<< ' ';
  31.     err(++it, args...);
  32. }
  33.  
  34.  
  35. /*
  36. ######################################################################
  37. #######################   THE   BIG   INT   ##########################
  38.  */
  39. //REMEMBER :
  40. //for 1e6 calculations of two numbers of order of 2^64:
  41. //    for addition : 2.7 s
  42. //    for multiplication : 4 s
  43.  
  44. struct bigint {
  45.     static const int base = 1000000000;
  46.     static const int base_digits = 9;
  47.  
  48.     vector<int> a;
  49.     int sign;
  50.     /*<arpa>*/
  51.     int size(){
  52.         if(a.empty())return 0;
  53.         int ans=(a.size()-1)*base_digits;
  54.         int ca=a.back();
  55.         while(ca)
  56.             ans++,ca/=10;
  57.         return ans;
  58.     }
  59.     bigint operator ^(const bigint &v){
  60.         bigint ans=1,a=*this,b=v;
  61.         while(!b.isZero()){
  62.             if(b%2)
  63.                 ans*=a;
  64.             a*=a,b/=2;
  65.         }
  66.         return ans;
  67.     }
  68.     string to_string(){
  69.         stringstream ss;
  70.         ss << *this;
  71.         string s;
  72.         ss >> s;
  73.         return s;
  74.     }
  75.     int sumof(){
  76.         string s = to_string();
  77.         int ans = 0;
  78.         for(auto c : s)  ans += c - '0';
  79.         return ans;
  80.     }
  81.     /*</arpa>*/
  82.     bigint() :
  83.         sign(1) {
  84.         }
  85.  
  86.     bigint(long long v) {
  87.         *this = v;
  88.     }
  89.  
  90.     bigint(const string &s) {
  91.         read(s);
  92.     }
  93.  
  94.     void operator=(const bigint &v) {
  95.         sign = v.sign;
  96.         a = v.a;
  97.     }
  98.  
  99.     void operator=(long long v) {
  100.         sign = 1;
  101.         a.clear();
  102.         if (v < 0)
  103.             sign = -1, v = -v;
  104.         for (; v > 0; v = v / base)
  105.             a.push_back(v % base);
  106.     }
  107.  
  108.     bigint operator+(const bigint &v) const {
  109.         if (sign == v.sign) {
  110.             bigint res = v;
  111.  
  112.             for (int i = 0, carry = 0; i < (int) max(a.size(), v.a.size()) || carry; ++i) {
  113.                 if (i == (int) res.a.size())
  114.                     res.a.push_back(0);
  115.                 res.a[i] += carry + (i < (int) a.size() ? a[i] : 0);
  116.                 carry = res.a[i] >= base;
  117.                 if (carry)
  118.                     res.a[i] -= base;
  119.             }
  120.             return res;
  121.         }
  122.         return *this - (-v);
  123.     }
  124.  
  125.     bigint operator-(const bigint &v) const {
  126.         if (sign == v.sign) {
  127.             if (abs() >= v.abs()) {
  128.                 bigint res = *this;
  129.                 for (int i = 0, carry = 0; i < (int) v.a.size() || carry; ++i) {
  130.                     res.a[i] -= carry + (i < (int) v.a.size() ? v.a[i] : 0);
  131.                     carry = res.a[i] < 0;
  132.                     if (carry)
  133.                         res.a[i] += base;
  134.                 }
  135.                 res.trim();
  136.                 return res;
  137.             }
  138.             return -(v - *this);
  139.         }
  140.         return *this + (-v);
  141.     }
  142.  
  143.     void operator*=(int v) {
  144.         if (v < 0)
  145.             sign = -sign, v = -v;
  146.         for (int i = 0, carry = 0; i < (int) a.size() || carry; ++i) {
  147.             if (i == (int) a.size())
  148.                 a.push_back(0);
  149.             long long cur = a[i] * (long long) v + carry;
  150.             carry = (int) (cur / base);
  151.             a[i] = (int) (cur % base);
  152.             //asm("divl %%ecx" : "=a"(carry), "=d"(a[i]) : "A"(cur), "c"(base));
  153.         }
  154.         trim();
  155.     }
  156.  
  157.     bigint operator*(int v) const {
  158.         bigint res = *this;
  159.         res *= v;
  160.         return res;
  161.     }
  162.  
  163.     void operator*=(long long v) {
  164.         if (v < 0)
  165.             sign = -sign, v = -v;
  166.         for (int i = 0, carry = 0; i < (int) a.size() || carry; ++i) {
  167.             if (i == (int) a.size())
  168.                 a.push_back(0);
  169.             long long cur = a[i] * (long long) v + carry;
  170.             carry = (int) (cur / base);
  171.             a[i] = (int) (cur % base);
  172.             //asm("divl %%ecx" : "=a"(carry), "=d"(a[i]) : "A"(cur), "c"(base));
  173.         }
  174.         trim();
  175.     }
  176.  
  177.     bigint operator*(long long v) const {
  178.         bigint res = *this;
  179.         res *= v;
  180.         return res;
  181.     }
  182.  
  183.     friend pair<bigint, bigint> divmod(const bigint &a1, const bigint &b1) {
  184.         int norm = base / (b1.a.back() + 1);
  185.         bigint a = a1.abs() * norm;
  186.         bigint b = b1.abs() * norm;
  187.         bigint q, r;
  188.         q.a.resize(a.a.size());
  189.  
  190.         for (int i = a.a.size() - 1; i >= 0; i--) {
  191.             r *= base;
  192.             r += a.a[i];
  193.             int s1 = r.a.size() <= b.a.size() ? 0 : r.a[b.a.size()];
  194.             int s2 = r.a.size() <= b.a.size() - 1 ? 0 : r.a[b.a.size() - 1];
  195.             int d = ((long long) base * s1 + s2) / b.a.back();
  196.             r -= b * d;
  197.             while (r < 0)
  198.                 r += b, --d;
  199.             q.a[i] = d;
  200.         }
  201.  
  202.         q.sign = a1.sign * b1.sign;
  203.         r.sign = a1.sign;
  204.         q.trim();
  205.         r.trim();
  206.         return make_pair(q, r / norm);
  207.     }
  208.  
  209.     bigint operator/(const bigint &v) const {
  210.         return divmod(*this, v).first;
  211.     }
  212.  
  213.     bigint operator%(const bigint &v) const {
  214.         return divmod(*this, v).second;
  215.     }
  216.  
  217.     void operator/=(int v) {
  218.         if (v < 0)
  219.             sign = -sign, v = -v;
  220.         for (int i = (int) a.size() - 1, rem = 0; i >= 0; --i) {
  221.             long long cur = a[i] + rem * (long long) base;
  222.             a[i] = (int) (cur / v);
  223.             rem = (int) (cur % v);
  224.         }
  225.         trim();
  226.     }
  227.  
  228.     bigint operator/(int v) const {
  229.         bigint res = *this;
  230.         res /= v;
  231.         return res;
  232.     }
  233.  
  234.     int operator%(int v) const {
  235.         if (v < 0)
  236.             v = -v;
  237.         int m = 0;
  238.         for (int i = a.size() - 1; i >= 0; --i)
  239.             m = (a[i] + m * (long long) base) % v;
  240.         return m * sign;
  241.     }
  242.  
  243.     void operator+=(const bigint &v) {
  244.         *this = *this + v;
  245.     }
  246.     void operator-=(const bigint &v) {
  247.         *this = *this - v;
  248.     }
  249.     void operator*=(const bigint &v) {
  250.         *this = *this * v;
  251.     }
  252.     void operator/=(const bigint &v) {
  253.         *this = *this / v;
  254.     }
  255.  
  256.     bool operator<(const bigint &v) const {
  257.         if (sign != v.sign)
  258.             return sign < v.sign;
  259.         if (a.size() != v.a.size())
  260.             return a.size() * sign < v.a.size() * v.sign;
  261.         for (int i = a.size() - 1; i >= 0; i--)
  262.             if (a[i] != v.a[i])
  263.                 return a[i] * sign < v.a[i] * sign;
  264.         return false;
  265.     }
  266.  
  267.     bool operator>(const bigint &v) const {
  268.         return v < *this;
  269.     }
  270.     bool operator<=(const bigint &v) const {
  271.         return !(v < *this);
  272.     }
  273.     bool operator>=(const bigint &v) const {
  274.         return !(*this < v);
  275.     }
  276.     bool operator==(const bigint &v) const {
  277.         return !(*this < v) && !(v < *this);
  278.     }
  279.     bool operator!=(const bigint &v) const {
  280.         return *this < v || v < *this;
  281.     }
  282.  
  283.     void trim() {
  284.         while (!a.empty() && !a.back())
  285.             a.pop_back();
  286.         if (a.empty())
  287.             sign = 1;
  288.     }
  289.  
  290.     bool isZero() const {
  291.         return a.empty() || (a.size() == 1 && !a[0]);
  292.     }
  293.  
  294.     bigint operator-() const {
  295.         bigint res = *this;
  296.         res.sign = -sign;
  297.         return res;
  298.     }
  299.  
  300.     bigint abs() const {
  301.         bigint res = *this;
  302.         res.sign *= res.sign;
  303.         return res;
  304.     }
  305.  
  306.     long long longValue() const {
  307.         long long res = 0;
  308.         for (int i = a.size() - 1; i >= 0; i--)
  309.             res = res * base + a[i];
  310.         return res * sign;
  311.     }
  312.  
  313.     friend bigint gcd(const bigint &a, const bigint &b) {
  314.         return b.isZero() ? a : gcd(b, a % b);
  315.     }
  316.     friend bigint lcm(const bigint &a, const bigint &b) {
  317.         return a / gcd(a, b) * b;
  318.     }
  319.  
  320.     void read(const string &s) {
  321.         sign = 1;
  322.         a.clear();
  323.         int pos = 0;
  324.         while (pos < (int) s.size() && (s[pos] == '-' || s[pos] == '+')) {
  325.             if (s[pos] == '-')
  326.                 sign = -sign;
  327.             ++pos;
  328.         }
  329.         for (int i = s.size() - 1; i >= pos; i -= base_digits) {
  330.             int x = 0;
  331.             for (int j = max(pos, i - base_digits + 1); j <= i; j++)
  332.                 x = x * 10 + s[j] - '0';
  333.             a.push_back(x);
  334.         }
  335.         trim();
  336.     }
  337.  
  338.     friend istream& operator>>(istream &stream, bigint &v) {
  339.         string s;
  340.         stream >> s;
  341.         v.read(s);
  342.         return stream;
  343.     }
  344.  
  345.     friend ostream& operator<<(ostream &stream, const bigint &v) {
  346.         if (v.sign == -1)
  347.             stream << '-';
  348.         stream << (v.a.empty() ? 0 : v.a.back());
  349.         for (int i = (int) v.a.size() - 2; i >= 0; --i)
  350.             stream << setw(base_digits) << setfill('0') << v.a[i];
  351.         return stream;
  352.     }
  353.  
  354.     static vector<int> convert_base(const vector<int> &a, int old_digits, int new_digits) {
  355.         vector<long long> p(max(old_digits, new_digits) + 1);
  356.         p[0] = 1;
  357.         for (int i = 1; i < (int) p.size(); i++)
  358.             p[i] = p[i - 1] * 10;
  359.         vector<int> res;
  360.         long long cur = 0;
  361.         int cur_digits = 0;
  362.         for (int i = 0; i < (int) a.size(); i++) {
  363.             cur += a[i] * p[cur_digits];
  364.             cur_digits += old_digits;
  365.             while (cur_digits >= new_digits) {
  366.                 res.push_back(int(cur % p[new_digits]));
  367.                 cur /= p[new_digits];
  368.                 cur_digits -= new_digits;
  369.             }
  370.         }
  371.         res.push_back((int) cur);
  372.         while (!res.empty() && !res.back())
  373.             res.pop_back();
  374.         return res;
  375.     }
  376.  
  377.     typedef vector<long long> vll;
  378.  
  379.     static vll karatsubaMultiply(const vll &a, const vll &b) {
  380.         int n = a.size();
  381.         vll res(n + n);
  382.         if (n <= 32) {
  383.             for (int i = 0; i < n; i++)
  384.                 for (int j = 0; j < n; j++)
  385.                     res[i + j] += a[i] * b[j];
  386.             return res;
  387.         }
  388.  
  389.         int k = n >> 1;
  390.         vll a1(a.begin(), a.begin() + k);
  391.         vll a2(a.begin() + k, a.end());
  392.         vll b1(b.begin(), b.begin() + k);
  393.         vll b2(b.begin() + k, b.end());
  394.  
  395.         vll a1b1 = karatsubaMultiply(a1, b1);
  396.         vll a2b2 = karatsubaMultiply(a2, b2);
  397.  
  398.         for (int i = 0; i < k; i++)
  399.             a2[i] += a1[i];
  400.         for (int i = 0; i < k; i++)
  401.             b2[i] += b1[i];
  402.  
  403.         vll r = karatsubaMultiply(a2, b2);
  404.         for (int i = 0; i < (int) a1b1.size(); i++)
  405.             r[i] -= a1b1[i];
  406.         for (int i = 0; i < (int) a2b2.size(); i++)
  407.             r[i] -= a2b2[i];
  408.  
  409.         for (int i = 0; i < (int) r.size(); i++)
  410.             res[i + k] += r[i];
  411.         for (int i = 0; i < (int) a1b1.size(); i++)
  412.             res[i] += a1b1[i];
  413.         for (int i = 0; i < (int) a2b2.size(); i++)
  414.             res[i + n] += a2b2[i];
  415.         return res;
  416.     }
  417.  
  418.     bigint operator*(const bigint &v) const {
  419.         vector<int> a6 = convert_base(this->a, base_digits, 6);
  420.         vector<int> b6 = convert_base(v.a, base_digits, 6);
  421.         vll a(a6.begin(), a6.end());
  422.         vll b(b6.begin(), b6.end());
  423.         while (a.size() < b.size())
  424.             a.push_back(0);
  425.         while (b.size() < a.size())
  426.             b.push_back(0);
  427.         while (a.size() & (a.size() - 1))
  428.             a.push_back(0), b.push_back(0);
  429.         vll c = karatsubaMultiply(a, b);
  430.         bigint res;
  431.         res.sign = sign * v.sign;
  432.         for (int i = 0, carry = 0; i < (int) c.size(); i++) {
  433.             long long cur = c[i] + carry;
  434.             res.a.push_back((int) (cur % 1000000));
  435.             carry = (int) (cur / 1000000);
  436.         }
  437.         res.a = convert_base(res.a, 6, base_digits);
  438.         res.trim();
  439.         return res;
  440.     }
  441. };
  442. /*
  443. #######################   THE   BIG   INT   ##########################
  444. ######################################################################
  445.  */
  446.  
  447. const int N = 105;
  448. bigint min_taken[N], max_taken[N], min_not_taken[N], max_not_taken[N], dp[N];
  449. vector <int> ar;
  450. int n;
  451.  
  452. bigint solve() {
  453.    max_taken[0] = ar[0]; min_taken[0] = ar[0];
  454.    min_not_taken[0] = INT_MIN; max_not_taken[0] = INT_MIN;
  455.    dp[0] = max(max(max_taken[0], max_not_taken[0]), max(min_taken[0], min_not_taken[0]));
  456.    for (int i = 1; i < n; ++i) {
  457.       bigint cur = ar[i];
  458.       max_taken[i] = max(max(min_taken[i-1]*ar[i], max_taken[i-1]*ar[i]), cur);
  459.       min_taken[i] = min(min(min_taken[i-1]*ar[i], max_taken[i-1]*ar[i]), cur);
  460.       max_not_taken[i] = max(max_taken[i-1],max_not_taken[i-1]);
  461.       min_not_taken[i] = min(min_taken[i-1],min_not_taken[i-1]);
  462.       dp[i] = max(max(max_taken[i], max_not_taken[i]), max(min_taken[i], min_not_taken[i]));
  463.    }
  464.    return dp[n-1];
  465. }
  466.  
  467.  
  468. signed main() {
  469.    IOS; PREC;
  470.    int tmp;
  471.    while (cin.peek() != EOF) {
  472.       ar.clear();
  473.       while (cin >> tmp, tmp != -999999) {
  474.          ar.push_back(tmp);
  475.       }
  476.       n = (int)ar.size();
  477.       cout << solve() << '\n';
  478.       cin.ignore();
  479.    }
  480.  
  481.    return EXIT_SUCCESS;
  482. }
Add Comment
Please, Sign In to add comment