Advertisement
Guest User

PLUSEQ - ashmelev

a guest
Jun 11th, 2018
249
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 10.25 KB | None | 0 0
  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstdlib>
  4. #include <cmath>
  5. #include <algorithm>
  6. #include <vector>
  7. #include <map>
  8. #include <set>
  9. #include <bitset>
  10. #include <queue>
  11. #include <stack>
  12. #include <sstream>
  13. #include <cstring>
  14. #include <numeric>
  15. #include <ctime>
  16. #include <cassert>
  17.  
  18. #define re return
  19. #define fi first
  20. #define se second
  21. #define mp make_pair
  22. #define pb emplace_back
  23. #define all(x) (x).begin(), (x).end()
  24. #define sz(x) ((int) (x).size())
  25. #define rep(i, n) for (int i = 0; i < (n); i++)
  26. #define rrep(i, n) for (int i = (n) - 1; i >= 0; i--)
  27. #define y0 y32479
  28. #define y1 y95874
  29. #define fill(x, y) memset(x, y, sizeof(x))
  30. #define sqr(x) ((x) * (x))
  31. #define sqrt(x) sqrt(abs(x))
  32. #define unq(x) (x.resize(unique(all(x)) - x.begin()))
  33. #define spc(i,n) " \n"[i == n - 1]
  34. #define next next239
  35. #define prev prev239
  36. #define ba back()
  37. #define last(x) x[sz(x) - 1]
  38. #define deb(x) cout << #x << " = " << (x) << endl
  39. #define deba(x) do { cout << #x << " (size: " << sz(x) << ") = " << \
  40.     "{"; for (auto o : x) cout << o << ","; cout << "}" << endl;} while (0)
  41.  
  42. using namespace std;
  43.  
  44. typedef vector<int> vi;
  45. typedef vector<vi> vvi;
  46. typedef pair<int, int> ii;
  47. typedef vector<ii> vii;
  48. typedef vector<string> vs;
  49. typedef long long ll;
  50. typedef pair<ll, ll> pll;
  51. typedef vector<ll> vll;
  52. typedef long double LD;
  53.  
  54. template<class T> T abs(T x) { return x > 0 ? x : -x;}
  55.  
  56. template<class T> string toString(T x) {
  57.     ostringstream sout;
  58.     sout << x;
  59.     return sout.str();
  60. }
  61.  
  62. int nint() {
  63.     int x;
  64.     scanf("%d", &x);
  65.     re x;
  66. }
  67.  
  68. string s;
  69. string res;
  70. int n;
  71.  
  72. string update(string s) {
  73.     int p = 0;
  74.     while (p < sz(s) - 1 && s[p] == 48) {
  75.         p++;
  76.     }
  77.     re s.substr(p);
  78. }
  79.  
  80. bool fs(string &s1, string &s2) {
  81.     int p1 = 0, p2 = 0;
  82.     while (p1 < sz(s1) && s1[p1] == 48)
  83.         p1++;
  84.     while (p2 < sz(s2) && s2[p2] == 48)
  85.         p2++;
  86.     if (sz(s1) - p1 != sz(s2) - p2)
  87.         re sz(s1) - p1 < sz(s2) - p2;
  88.  
  89.     while (p1 < sz(s1)) {
  90.         if (s1[p1] > s2[p2])
  91.             re 0;
  92.         if (s1[p1] < s2[p2])
  93.             re 1;
  94.         p1++;
  95.         p2++;
  96.     }
  97.     re 0;
  98. }
  99.  
  100. bool f(ii o1, ii o2) {
  101.     int p1 = o1.fi;
  102.     int d1 = o1.se;
  103.     int p2 = o2.fi;
  104.     int d2 = o2.se;
  105.     string s1 = s.substr(p1, d1);
  106.     string s2 = s.substr(p2, d2);
  107.     re fs(s1, s2);
  108. }
  109.  
  110. string sub(string a, string &b) {
  111.     int f = 0;
  112.     int p1 = sz(a) - 1;
  113.     int p2 = sz(b) - 1;
  114.     while (p2 >= 0) {
  115.         int x = a[p1] - f - b[p2--];
  116.         if (x < 0) {
  117.             f = 1;
  118.             x += 10;
  119.         }
  120.         else
  121.             f = 0;
  122.  
  123.         a[p1--] = (char)(x ^ 48);
  124.     }
  125.  
  126.     while (f) {
  127.         a[p1]--;
  128.         if (a[p1] == 47) {
  129.             a[p1] = 57;
  130.             p1--;
  131.         }
  132.         else
  133.             break;
  134.     }
  135.  
  136.     if (a[0] == '0')
  137.         re update(a);
  138.     else
  139.         re a;
  140. }
  141.  
  142. vii v;
  143. int bro[130];
  144. int st[130];
  145. ll was1, was2;
  146. ll mask1[8000], mask2[8000];
  147. string ss[8000];
  148. int ssum[8000];
  149. ll sval[8000];
  150. ll sval2[130][130];
  151.  
  152. inline int check(int pos) {
  153.     if (was1 & mask1[pos])
  154.         re 0;
  155.     if (was2 & mask2[pos])
  156.         re 0;
  157.     re 1;
  158. }
  159.  
  160. inline void apply(int pos) {
  161.     was1 ^= mask1[pos];
  162.     was2 ^= mask2[pos];
  163. }
  164.  
  165. inline void remove(int pos) {
  166.     was1 ^= mask1[pos];
  167.     was2 ^= mask2[pos];
  168. }
  169.  
  170. inline int getW(int pos) {
  171.     if (pos < 60)
  172.         re (was1 >> pos) & 1;
  173.     re (was2 >> (pos - 60)) & 1;
  174. }
  175.  
  176. inline void update(int &pos) {
  177.     while (pos < sz(v) && !check(pos))
  178.         pos++;
  179. }
  180.  
  181. ll table3[30][10][130][130];
  182.  
  183. ll getans3(int l, int r, int d, int ma) {
  184.     if (l > r)
  185.         re 0;
  186.  
  187.     if (r - l + 1 <= d)
  188.         re sval2[l][r];
  189.  
  190.     ll &ans = table3[d][ma][l][r];
  191.     if (ans != 0)
  192.         re ans;
  193.  
  194.     if (d == 1) {
  195.         ans = 0;
  196.         for (int i = l; i <= r; i++)
  197.             ans += s[i] - 48;
  198.         re ans;
  199.     }
  200.  
  201.     ans = 0;
  202.     ll pre = 0;
  203.     for (int p = l; p <= r; p++) {
  204.         int plen = p - l + 1;
  205.         if (plen > d)
  206.             break;
  207.  
  208.         pre = pre * 10 + s[p] - 48;
  209.         ans = max(ans, pre + getans3(p + 1, r, d, ma));
  210.     }
  211.     re ans;
  212. }
  213.  
  214. double table2[130][130][130][10];
  215. int st10[6] = {1, 10, 100, 1000, 10000, 100000};
  216.  
  217. double getans2(int l, int r, int d, int ma) {
  218.     if (l > r)
  219.         re 0;
  220.  
  221.     double &ans = table2[l][r][d][ma];
  222.     if (ans > 1e-3)
  223.         re ans;
  224.  
  225.     if (d == 1) {
  226.         ans = 0;
  227.         for (int i = l; i <= r; i++)
  228.             ans += min(s[i] - 48, ma);
  229.         re ans;
  230.     }
  231.  
  232.     if (l == r) {
  233.         ans = s[l] - 48;
  234.         if (d == 2)
  235.             ans /= 10;
  236.         if (d > 2)
  237.             ans /= 100;
  238.         re ans;
  239.     }
  240.  
  241.     if (r - l + 1 == d - 1) {
  242.         ans = (s[l] - 48) / 10.0 + (s[l + 1] - 47) / 100.0;
  243.         re ans;
  244.     }
  245.  
  246.     if (r - l + 1 < d - 1) {
  247.         ans = (s[l] - 47) / (double)st10[min(5, d - (r - l + 1))];
  248.         re ans;
  249.     }
  250.  
  251.     ans = min(s[l] - 48, ma) + (s[l + 1] - 47) / 10.0 + getans2(l + d, r, d, ma);
  252.     for (int p = l + 1; p + d - 1 <= r; p++) {
  253.         int plen = p - l;
  254.         if (plen >= d)
  255.             break;
  256.         double bu = s[l] - 48;
  257.         if (plen > 1)
  258.             bu += (s[l + 1] - 47) / 10.0;
  259.         bu /= st10[min(d - plen, 5)];
  260.         ans = max(ans, bu + getans2(p, r, d, ma));
  261.     }
  262.     re ans;
  263. }
  264.  
  265. vii pro;
  266.  
  267. int addPro(int pos, int &kk, int &cl, int &cr) {
  268.     int l = v[pos].fi;
  269.     int r = l + v[pos].se - 1;
  270.     ii globus[2];
  271.  
  272.     int id = 0;
  273.     rep(i, sz(pro)) {
  274.         if (pro[i].fi <= l && pro[i].se >= r) {
  275.             id = i;
  276.             break;
  277.         }
  278.     }
  279.  
  280.     cl = pro[id].fi;
  281.     cr = pro[id].se;
  282.  
  283.     kk = 0;
  284.     if (cl != l)
  285.         globus[kk++] = mp(cl, l - 1);
  286.     if (cr != r)
  287.         globus[kk++] = mp(r + 1, cr);
  288.  
  289.     if (kk == 0) {
  290.         swap(pro.back(), pro[id]);
  291.         pro.pop_back();
  292.     }
  293.     if (kk >= 1)
  294.         pro[id] = globus[0];
  295.     if (kk == 2)
  296.         pro.pb(globus[1]);
  297.  
  298.     re id;
  299. }
  300.  
  301. inline void remPro(int id, int kk, int cl, int cr) {
  302.     if (kk == 2)
  303.         pro.pop_back();
  304.     if (kk >= 1)
  305.         pro[id] = mp(cl, cr);
  306.     if (kk == 0) {
  307.         pro.pb(mp(cl, cr));
  308.         swap(pro.back(), pro[id]);
  309.     }
  310. }
  311.  
  312. int csum;
  313. int smallC;
  314.  
  315. inline int tooBigSmall(ll cur, int pos, int flag) {
  316.     int cd = v[pos].se;
  317.  
  318.     if (cur > sval[pos] * ((n - smallC) / cd + 1))
  319.         if (cur > sval[pos] * (2 * (n - smallC) / cd + 1))
  320.             re 1;
  321.  
  322.     int dig = ss[pos][0] ^ 48;
  323.     ll sum = 0;
  324.     for (ii lr : pro) {
  325.         int l = lr.fi;
  326.         int r = lr.se;
  327.  
  328.         sum += getans3(l, r, cd, dig);
  329.         if (sum >= cur)
  330.             re 0;
  331.     }
  332.  
  333.     re 1;
  334. }
  335.  
  336. int goSmall(int pos, ll cur) {
  337.     if (cur < csum)
  338.         re 0;
  339.  
  340.     if (tooBigSmall(cur, pos, 0))
  341.         re 0;
  342.  
  343.     int dd = 0;
  344.     ll scur = cur;
  345.  
  346.     if (scur >= 1000000000) {
  347.         scur /= 1000000000;
  348.         dd += 9;
  349.     }
  350.  
  351.     if (scur >= 100000) {
  352.         scur /= 100000;
  353.         dd += 5;
  354.     }
  355.  
  356.     if (scur >= 1000) {
  357.         scur /= 1000;
  358.         dd += 3;
  359.     }
  360.  
  361.     while (scur >= 10) {
  362.         scur /= 10;
  363.         dd++;
  364.     }
  365.     dd++;
  366.  
  367.     pos = max(pos, st[dd]);
  368.  
  369.     update(pos);
  370.  
  371.     if (pos == sz(v))
  372.         re 0;
  373.  
  374.     while (pos < sz(v)) {
  375.         update(pos);
  376.         if (cur < sval[pos]) {
  377.             pos++;
  378.             continue;
  379.         }
  380.         else
  381.             break;
  382.     }
  383.  
  384.     while (pos < sz(v)) {
  385.         update(pos);
  386.  
  387.         if (pos == sz(v))
  388.             re 0;
  389.  
  390.         if (tooBigSmall(cur, pos, 0))
  391.             re 0;
  392.  
  393.         if (sval[pos] == cur)
  394.             if (smallC + sz(ss[pos]) == n) {
  395.                 bro[v[pos].fi] = 1;
  396.                 re 1;
  397.             }
  398.  
  399.         vii spro = pro;
  400.  
  401.         int kk = 0, cl = 0, cr = 0;
  402.         int id = addPro(pos, kk, cl, cr);
  403.  
  404.         csum -= ssum[pos];
  405.         smallC += v[pos].se;
  406.         apply(pos);
  407.         if (goSmall(pos + 1, cur - sval[pos])) {
  408.             bro[v[pos].fi] = 1;
  409.             re 1;
  410.         }
  411.         remove(pos);
  412.         smallC -= v[pos].se;
  413.         csum += ssum[pos];
  414.  
  415.         remPro(id, kk, cl, cr);
  416.  
  417.         if (v[pos].se <= 1)
  418.             re 0;
  419.         pos++;
  420.     }
  421.  
  422.     re 0;
  423. }
  424.  
  425. int gg[150];
  426.  
  427. bool tooBig(string &cur, int pos) {
  428.     int cd = v[pos].se;
  429.     int dd = sz(cur);
  430.  
  431.     int pre = 0;
  432.     rep(i, dd - cd + 1) {
  433.         pre = pre * 10 + cur[i] - 48;
  434.         if (pre > 10 * (n / cd + 1))
  435.             re 1;
  436.     }
  437.  
  438.     rep(i, dd)
  439.         gg[i] = 0;
  440.  
  441.     int ok = 0;
  442.     for (ii lr : pro) {
  443.         int l = lr.fi;
  444.         int r = lr.se;
  445.  
  446.         if (r - l + 1 <= cd) {
  447.             for (int i = l; i <= r; i++) {
  448.                 if (r - i < cd - 1)
  449.                     gg[r - i] += s[i] ^ 48;
  450.                 else
  451.                     gg[r - i] += min(s[i], ss[pos][0]) ^ 48;
  452.             }
  453.         }
  454.         else {
  455.             int tmp = (int)(getans2(l, r, cd, ss[pos][0] ^ 48) + 1);
  456.             gg[cd - 1] += tmp;
  457.         }
  458.     }
  459.  
  460.     if (!ok) {
  461.         int f = 0;
  462.         rep(i, dd) {
  463.             int o = gg[i] + f;
  464.             f = o / 10;
  465.             gg[i] = o % 10;
  466.         }
  467.         if (!f)
  468.         rep(i, dd) {
  469.             int e = (cur[i] ^ 48) - gg[dd - i - 1];
  470.             if (e > 0)
  471.                 re 1;
  472.             if (e < 0)
  473.                 re 0;
  474.         }
  475.     }
  476.  
  477.     re 0;
  478. }
  479.  
  480. int go(int pos, string cur, int c, int csum) {
  481.     int dd = sz(cur);
  482.     pos = max(pos, st[dd]);
  483.  
  484.     if (dd <= 18) {
  485.         ll o = 0;
  486.         rep(i, dd)
  487.             o = o * 10 + cur[i] - 48;
  488.         ::csum = csum;
  489.         ::smallC = c;
  490.         re goSmall(pos, o);
  491.     }
  492.  
  493.     update(pos);
  494.  
  495.     while (pos < sz(v)) {
  496.         update(pos);
  497.         if (fs(cur, ::ss[pos])) {
  498.             pos++;
  499.             continue;
  500.         }
  501.         else
  502.             break;
  503.     }
  504.  
  505.     while (pos < sz(v)) {
  506.         update(pos);
  507.  
  508.         if (pos == sz(v))
  509.             re 0;
  510.  
  511.         if (tooBig(cur, pos))
  512.             re 0;
  513.  
  514.         if (ss[pos] == cur)
  515.             if (c + sz(ss[pos]) == n) {
  516.                 bro[v[pos].fi] = 1;
  517.                 re 1;
  518.             }
  519.  
  520.         int kk = 0, cl = 0, cr = 0;
  521.         int id = addPro(pos, kk, cl, cr);
  522.  
  523.         apply(pos);
  524.         if (go(pos + 1, sub(cur, ::ss[pos]), c + v[pos].se, csum - ssum[pos])) {
  525.             bro[v[pos].fi] = 1;
  526.             re 1;
  527.         }
  528.         remove(pos);
  529.  
  530.         remPro(id, kk, cl, cr);
  531.  
  532.         if (v[pos].se <= 1)
  533.             re 0;
  534.         pos++;
  535.     }
  536.  
  537.     re 0;
  538. }
  539.  
  540. void prepare() {
  541.     n = sz(s);
  542.     fill(bro, 0);
  543.     was1 = was2 = 0;
  544.     pro.clear();
  545.  
  546.     rep(i, n)
  547.     for (int j = i; j < n; j++) {
  548.         for (int d = 1; d <= j - i + 1; d++)
  549.         for (int ma = 1; ma <= 9; ma++)
  550.             table2[i][j][d][ma] = 0;
  551.     }
  552.  
  553.     rep(i, n)
  554.     for (int j = i; j < n; j++) {
  555.         for (int d = 0; d <= 18; d++)
  556.         for (int ma = 0; ma <= 9; ma++)
  557.             table3[d][ma][i][j] = 0;
  558.     }
  559.  
  560.     rep(i, n)
  561.     for (int j = i; j - i + 1 <= 18; j++) {
  562.         ll a = 0;
  563.         for (int k = i; k <= j; k++)
  564.             a = a * 10 + s[k] - 48;
  565.         sval2[i][j] = a;
  566.     }
  567.  
  568.     v.clear();
  569.     rep(i, sz(s))
  570.     for (int d = 1; i + d <= sz(s); d++) {
  571.         if (d > 1 && s[i] == '0')
  572.             continue;
  573.         v.pb(i, d);
  574.     }
  575.  
  576.     sort(all(v), f);
  577.     reverse(all(v));
  578.  
  579.     rep(i, n + 1)
  580.         st[i] = 9000;
  581.  
  582.     rep(i, sz(v)) {
  583.         int p = v[i].fi;
  584.         int len = v[i].se;
  585.         ll m1 = 0, m2 = 0;
  586.         ssum[i] = 0;
  587.         ll val = 0;
  588.         rep(j, n)
  589.             if (j >= p && j < p + len) {
  590.                 val = val * 10 + s[j] - 48;
  591.                 if (j < 60)
  592.                     m1 |= (1ll << j);
  593.                 else
  594.                     m2 |= (1ll << (j - 60));
  595.                 ssum[i] += s[j] - 48;
  596.             }
  597.         mask1[i] = m1;
  598.         mask2[i] = m2;
  599.         sval[i] = val;
  600.  
  601.         ss[i] = update(s.substr(p, len));
  602.         st[sz(ss[i])] = min(st[sz(ss[i])], i);
  603.     }
  604. }
  605.  
  606. void solve1() {
  607.     prepare();
  608.  
  609.     pro.pb(0, n - 1);
  610.     go(1, res, 0, ssum[0]);
  611.  
  612.     rep(i, n) {
  613.         if (i && bro[i])
  614.             cout << "+";
  615.         cout << s[i];
  616.     }
  617.     cout << endl;
  618. }
  619.  
  620. void solve() {
  621.     cin >> s >> res;
  622.     res = update(res);
  623.     if (update(s) == res) {
  624.         cout << s << endl;
  625.         re;
  626.     }
  627.     solve1();
  628. }
  629.  
  630. int main() {
  631.     int tc = 1;
  632.     cin >> tc;
  633.     rep(tt, tc)
  634.         solve();
  635. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement