Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <cstdio>
- #include <cstdlib>
- #include <cmath>
- #include <algorithm>
- #include <vector>
- #include <map>
- #include <set>
- #include <bitset>
- #include <queue>
- #include <stack>
- #include <sstream>
- #include <cstring>
- #include <numeric>
- #include <ctime>
- #include <cassert>
- #define re return
- #define fi first
- #define se second
- #define mp make_pair
- #define pb emplace_back
- #define all(x) (x).begin(), (x).end()
- #define sz(x) ((int) (x).size())
- #define rep(i, n) for (int i = 0; i < (n); i++)
- #define rrep(i, n) for (int i = (n) - 1; i >= 0; i--)
- #define y0 y32479
- #define y1 y95874
- #define fill(x, y) memset(x, y, sizeof(x))
- #define sqr(x) ((x) * (x))
- #define sqrt(x) sqrt(abs(x))
- #define unq(x) (x.resize(unique(all(x)) - x.begin()))
- #define spc(i,n) " \n"[i == n - 1]
- #define next next239
- #define prev prev239
- #define ba back()
- #define last(x) x[sz(x) - 1]
- #define deb(x) cout << #x << " = " << (x) << endl
- #define deba(x) do { cout << #x << " (size: " << sz(x) << ") = " << \
- "{"; for (auto o : x) cout << o << ","; cout << "}" << endl;} while (0)
- using namespace std;
- typedef vector<int> vi;
- typedef vector<vi> vvi;
- typedef pair<int, int> ii;
- typedef vector<ii> vii;
- typedef vector<string> vs;
- typedef long long ll;
- typedef pair<ll, ll> pll;
- typedef vector<ll> vll;
- typedef long double LD;
- template<class T> T abs(T x) { return x > 0 ? x : -x;}
- template<class T> string toString(T x) {
- ostringstream sout;
- sout << x;
- return sout.str();
- }
- int nint() {
- int x;
- scanf("%d", &x);
- re x;
- }
- string s;
- string res;
- int n;
- string update(string s) {
- int p = 0;
- while (p < sz(s) - 1 && s[p] == 48) {
- p++;
- }
- re s.substr(p);
- }
- bool fs(string &s1, string &s2) {
- int p1 = 0, p2 = 0;
- while (p1 < sz(s1) && s1[p1] == 48)
- p1++;
- while (p2 < sz(s2) && s2[p2] == 48)
- p2++;
- if (sz(s1) - p1 != sz(s2) - p2)
- re sz(s1) - p1 < sz(s2) - p2;
- while (p1 < sz(s1)) {
- if (s1[p1] > s2[p2])
- re 0;
- if (s1[p1] < s2[p2])
- re 1;
- p1++;
- p2++;
- }
- re 0;
- }
- bool f(ii o1, ii o2) {
- int p1 = o1.fi;
- int d1 = o1.se;
- int p2 = o2.fi;
- int d2 = o2.se;
- string s1 = s.substr(p1, d1);
- string s2 = s.substr(p2, d2);
- re fs(s1, s2);
- }
- string sub(string a, string &b) {
- int f = 0;
- int p1 = sz(a) - 1;
- int p2 = sz(b) - 1;
- while (p2 >= 0) {
- int x = a[p1] - f - b[p2--];
- if (x < 0) {
- f = 1;
- x += 10;
- }
- else
- f = 0;
- a[p1--] = (char)(x ^ 48);
- }
- while (f) {
- a[p1]--;
- if (a[p1] == 47) {
- a[p1] = 57;
- p1--;
- }
- else
- break;
- }
- if (a[0] == '0')
- re update(a);
- else
- re a;
- }
- vii v;
- int bro[130];
- int st[130];
- ll was1, was2;
- ll mask1[8000], mask2[8000];
- string ss[8000];
- int ssum[8000];
- ll sval[8000];
- ll sval2[130][130];
- inline int check(int pos) {
- if (was1 & mask1[pos])
- re 0;
- if (was2 & mask2[pos])
- re 0;
- re 1;
- }
- inline void apply(int pos) {
- was1 ^= mask1[pos];
- was2 ^= mask2[pos];
- }
- inline void remove(int pos) {
- was1 ^= mask1[pos];
- was2 ^= mask2[pos];
- }
- inline int getW(int pos) {
- if (pos < 60)
- re (was1 >> pos) & 1;
- re (was2 >> (pos - 60)) & 1;
- }
- inline void update(int &pos) {
- while (pos < sz(v) && !check(pos))
- pos++;
- }
- ll table3[30][10][130][130];
- ll getans3(int l, int r, int d, int ma) {
- if (l > r)
- re 0;
- if (r - l + 1 <= d)
- re sval2[l][r];
- ll &ans = table3[d][ma][l][r];
- if (ans != 0)
- re ans;
- if (d == 1) {
- ans = 0;
- for (int i = l; i <= r; i++)
- ans += s[i] - 48;
- re ans;
- }
- ans = 0;
- ll pre = 0;
- for (int p = l; p <= r; p++) {
- int plen = p - l + 1;
- if (plen > d)
- break;
- pre = pre * 10 + s[p] - 48;
- ans = max(ans, pre + getans3(p + 1, r, d, ma));
- }
- re ans;
- }
- double table2[130][130][130][10];
- int st10[6] = {1, 10, 100, 1000, 10000, 100000};
- double getans2(int l, int r, int d, int ma) {
- if (l > r)
- re 0;
- double &ans = table2[l][r][d][ma];
- if (ans > 1e-3)
- re ans;
- if (d == 1) {
- ans = 0;
- for (int i = l; i <= r; i++)
- ans += min(s[i] - 48, ma);
- re ans;
- }
- if (l == r) {
- ans = s[l] - 48;
- if (d == 2)
- ans /= 10;
- if (d > 2)
- ans /= 100;
- re ans;
- }
- if (r - l + 1 == d - 1) {
- ans = (s[l] - 48) / 10.0 + (s[l + 1] - 47) / 100.0;
- re ans;
- }
- if (r - l + 1 < d - 1) {
- ans = (s[l] - 47) / (double)st10[min(5, d - (r - l + 1))];
- re ans;
- }
- ans = min(s[l] - 48, ma) + (s[l + 1] - 47) / 10.0 + getans2(l + d, r, d, ma);
- for (int p = l + 1; p + d - 1 <= r; p++) {
- int plen = p - l;
- if (plen >= d)
- break;
- double bu = s[l] - 48;
- if (plen > 1)
- bu += (s[l + 1] - 47) / 10.0;
- bu /= st10[min(d - plen, 5)];
- ans = max(ans, bu + getans2(p, r, d, ma));
- }
- re ans;
- }
- vii pro;
- int addPro(int pos, int &kk, int &cl, int &cr) {
- int l = v[pos].fi;
- int r = l + v[pos].se - 1;
- ii globus[2];
- int id = 0;
- rep(i, sz(pro)) {
- if (pro[i].fi <= l && pro[i].se >= r) {
- id = i;
- break;
- }
- }
- cl = pro[id].fi;
- cr = pro[id].se;
- kk = 0;
- if (cl != l)
- globus[kk++] = mp(cl, l - 1);
- if (cr != r)
- globus[kk++] = mp(r + 1, cr);
- if (kk == 0) {
- swap(pro.back(), pro[id]);
- pro.pop_back();
- }
- if (kk >= 1)
- pro[id] = globus[0];
- if (kk == 2)
- pro.pb(globus[1]);
- re id;
- }
- inline void remPro(int id, int kk, int cl, int cr) {
- if (kk == 2)
- pro.pop_back();
- if (kk >= 1)
- pro[id] = mp(cl, cr);
- if (kk == 0) {
- pro.pb(mp(cl, cr));
- swap(pro.back(), pro[id]);
- }
- }
- int csum;
- int smallC;
- inline int tooBigSmall(ll cur, int pos, int flag) {
- int cd = v[pos].se;
- if (cur > sval[pos] * ((n - smallC) / cd + 1))
- if (cur > sval[pos] * (2 * (n - smallC) / cd + 1))
- re 1;
- int dig = ss[pos][0] ^ 48;
- ll sum = 0;
- for (ii lr : pro) {
- int l = lr.fi;
- int r = lr.se;
- sum += getans3(l, r, cd, dig);
- if (sum >= cur)
- re 0;
- }
- re 1;
- }
- int goSmall(int pos, ll cur) {
- if (cur < csum)
- re 0;
- if (tooBigSmall(cur, pos, 0))
- re 0;
- int dd = 0;
- ll scur = cur;
- if (scur >= 1000000000) {
- scur /= 1000000000;
- dd += 9;
- }
- if (scur >= 100000) {
- scur /= 100000;
- dd += 5;
- }
- if (scur >= 1000) {
- scur /= 1000;
- dd += 3;
- }
- while (scur >= 10) {
- scur /= 10;
- dd++;
- }
- dd++;
- pos = max(pos, st[dd]);
- update(pos);
- if (pos == sz(v))
- re 0;
- while (pos < sz(v)) {
- update(pos);
- if (cur < sval[pos]) {
- pos++;
- continue;
- }
- else
- break;
- }
- while (pos < sz(v)) {
- update(pos);
- if (pos == sz(v))
- re 0;
- if (tooBigSmall(cur, pos, 0))
- re 0;
- if (sval[pos] == cur)
- if (smallC + sz(ss[pos]) == n) {
- bro[v[pos].fi] = 1;
- re 1;
- }
- vii spro = pro;
- int kk = 0, cl = 0, cr = 0;
- int id = addPro(pos, kk, cl, cr);
- csum -= ssum[pos];
- smallC += v[pos].se;
- apply(pos);
- if (goSmall(pos + 1, cur - sval[pos])) {
- bro[v[pos].fi] = 1;
- re 1;
- }
- remove(pos);
- smallC -= v[pos].se;
- csum += ssum[pos];
- remPro(id, kk, cl, cr);
- if (v[pos].se <= 1)
- re 0;
- pos++;
- }
- re 0;
- }
- int gg[150];
- bool tooBig(string &cur, int pos) {
- int cd = v[pos].se;
- int dd = sz(cur);
- int pre = 0;
- rep(i, dd - cd + 1) {
- pre = pre * 10 + cur[i] - 48;
- if (pre > 10 * (n / cd + 1))
- re 1;
- }
- rep(i, dd)
- gg[i] = 0;
- int ok = 0;
- for (ii lr : pro) {
- int l = lr.fi;
- int r = lr.se;
- if (r - l + 1 <= cd) {
- for (int i = l; i <= r; i++) {
- if (r - i < cd - 1)
- gg[r - i] += s[i] ^ 48;
- else
- gg[r - i] += min(s[i], ss[pos][0]) ^ 48;
- }
- }
- else {
- int tmp = (int)(getans2(l, r, cd, ss[pos][0] ^ 48) + 1);
- gg[cd - 1] += tmp;
- }
- }
- if (!ok) {
- int f = 0;
- rep(i, dd) {
- int o = gg[i] + f;
- f = o / 10;
- gg[i] = o % 10;
- }
- if (!f)
- rep(i, dd) {
- int e = (cur[i] ^ 48) - gg[dd - i - 1];
- if (e > 0)
- re 1;
- if (e < 0)
- re 0;
- }
- }
- re 0;
- }
- int go(int pos, string cur, int c, int csum) {
- int dd = sz(cur);
- pos = max(pos, st[dd]);
- if (dd <= 18) {
- ll o = 0;
- rep(i, dd)
- o = o * 10 + cur[i] - 48;
- ::csum = csum;
- ::smallC = c;
- re goSmall(pos, o);
- }
- update(pos);
- while (pos < sz(v)) {
- update(pos);
- if (fs(cur, ::ss[pos])) {
- pos++;
- continue;
- }
- else
- break;
- }
- while (pos < sz(v)) {
- update(pos);
- if (pos == sz(v))
- re 0;
- if (tooBig(cur, pos))
- re 0;
- if (ss[pos] == cur)
- if (c + sz(ss[pos]) == n) {
- bro[v[pos].fi] = 1;
- re 1;
- }
- int kk = 0, cl = 0, cr = 0;
- int id = addPro(pos, kk, cl, cr);
- apply(pos);
- if (go(pos + 1, sub(cur, ::ss[pos]), c + v[pos].se, csum - ssum[pos])) {
- bro[v[pos].fi] = 1;
- re 1;
- }
- remove(pos);
- remPro(id, kk, cl, cr);
- if (v[pos].se <= 1)
- re 0;
- pos++;
- }
- re 0;
- }
- void prepare() {
- n = sz(s);
- fill(bro, 0);
- was1 = was2 = 0;
- pro.clear();
- rep(i, n)
- for (int j = i; j < n; j++) {
- for (int d = 1; d <= j - i + 1; d++)
- for (int ma = 1; ma <= 9; ma++)
- table2[i][j][d][ma] = 0;
- }
- rep(i, n)
- for (int j = i; j < n; j++) {
- for (int d = 0; d <= 18; d++)
- for (int ma = 0; ma <= 9; ma++)
- table3[d][ma][i][j] = 0;
- }
- rep(i, n)
- for (int j = i; j - i + 1 <= 18; j++) {
- ll a = 0;
- for (int k = i; k <= j; k++)
- a = a * 10 + s[k] - 48;
- sval2[i][j] = a;
- }
- v.clear();
- rep(i, sz(s))
- for (int d = 1; i + d <= sz(s); d++) {
- if (d > 1 && s[i] == '0')
- continue;
- v.pb(i, d);
- }
- sort(all(v), f);
- reverse(all(v));
- rep(i, n + 1)
- st[i] = 9000;
- rep(i, sz(v)) {
- int p = v[i].fi;
- int len = v[i].se;
- ll m1 = 0, m2 = 0;
- ssum[i] = 0;
- ll val = 0;
- rep(j, n)
- if (j >= p && j < p + len) {
- val = val * 10 + s[j] - 48;
- if (j < 60)
- m1 |= (1ll << j);
- else
- m2 |= (1ll << (j - 60));
- ssum[i] += s[j] - 48;
- }
- mask1[i] = m1;
- mask2[i] = m2;
- sval[i] = val;
- ss[i] = update(s.substr(p, len));
- st[sz(ss[i])] = min(st[sz(ss[i])], i);
- }
- }
- void solve1() {
- prepare();
- pro.pb(0, n - 1);
- go(1, res, 0, ssum[0]);
- rep(i, n) {
- if (i && bro[i])
- cout << "+";
- cout << s[i];
- }
- cout << endl;
- }
- void solve() {
- cin >> s >> res;
- res = update(res);
- if (update(s) == res) {
- cout << s << endl;
- re;
- }
- solve1();
- }
- int main() {
- int tc = 1;
- cin >> tc;
- rep(tt, tc)
- solve();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement