aliqi

Maraton Contest1

Jan 20th, 2025 (edited)
203
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 21.94 KB | Source Code | 0 0
  1. #include <iostream>
  2. #include <string.h>
  3. #include <math.h>
  4. #include "td/utils/lz4.h"
  5. #include "td/utils/base64.h"
  6. #include "vm/boc.h"
  7. #include "vm/cells/CellSlice.h"
  8. using namespace std;
  9.  
  10. using PI = pair<int, int>;
  11. using VP = vector<PI>;
  12. using VS = vector<short>;
  13. using VI = vector<int>;
  14. using VC = vector<char>;
  15. using VB = vector<bool>;
  16. using BS = td::BufferSlice;
  17. using CD = td::Ref<vm::Cell>;
  18. using HS = vm::Cell::Hash;
  19. using CB = vm::CellBuilder;
  20. using CS = vm::CellSlice;
  21. #define FOR(i,a,b) for (int i = a; i < b; i ++)
  22. #define sz(x) (int)(x).size()
  23. #define all(x) begin(x), end(x)
  24. #define endl '\n'
  25. #define pb emplace_back
  26. int __lg(int n) {
  27.     int x = 0;
  28.     while ((1 << x) <= n) x++;
  29.     return x - 1;
  30. }
  31. struct WT {
  32.     int n, pw;
  33.     int inf = INT_MAX;
  34.     VI v;
  35.     void init(VI& _init) {
  36.         n = _init.size();
  37.         if (!n) return;
  38.         pw = 2 << __lg(n);
  39.         v.assign(pw << 1, inf);
  40.         for (int i = 0; i < n; i++) v[i + pw] = _init[i];
  41.         for (int i = pw - 1; i > 0; i--) v[i] = min(v[i << 1], v[i << 1 | 1]);
  42.     }
  43.     int get(int l, int r) {
  44.         l += pw, r += pw;
  45.         int rlt = inf;
  46.         while (l < r) {
  47.             if (l & 1) rlt = min(rlt, v[l]);
  48.             if (r & 1) rlt = min(rlt, v[r - 1]);
  49.             l = (l + 1) / 2, r /= 2;
  50.         }
  51.         return rlt;
  52.     }
  53. } wnt;
  54. struct SuffixArray {
  55.     VI v, A, B, cnt, sa, startPoss, lcp;
  56.     int len;
  57.     void rsort(VI& x, VI& y, int offset, int mx, int n) {
  58.         for (int i = 0; i < mx && i < cnt.size(); i++) cnt[i] = 0;
  59.         while (cnt.size() < mx) cnt.pb(0);
  60.         for (int i = 0; i < n; i++) cnt[v[x[i] + offset]] ++;
  61.         for (int i = 1; i < mx; i++) cnt[i] += cnt[i - 1];
  62.         for (int i = n - 1; i >= 0; i--) y[--cnt[v[x[i] + offset]]] = x[i];
  63.     }
  64.     bool comp(int x, int y) {
  65.         return v[x] == v[y] && v[x + 1] == v[y + 1] && v[x + 2] == v[y + 2];
  66.     }
  67.     void buildSA(int st, int mx) {
  68.         int n = v.size() - st;
  69.         int c0 = n / 3 + (n % 3 > 0), c1 = n / 3 + (n % 3 > 1), c2 = n / 3, cx = c1 + c2;
  70.         v.pb(0), v.pb(0), mx++;
  71.         A.clear();
  72.         for (int i = 0; i < n; i++) if (i % 3) A.pb(i);
  73.         if (B.size() < A.size()) B.resize(A.size());
  74.         rsort(A, B, st + 2, mx, cx);
  75.         rsort(B, A, st + 1, mx, cx);
  76.         rsort(A, B, st, mx, cx);
  77.         int cc = v.size(), cy = v.size() + c1, nx = v.size();
  78.         v.resize(v.size() + cx);
  79.         int cu = 1;
  80.         for (int i = 0; i < cx; i++) {
  81.             if (i && !comp(B[i] + st, B[i - 1] + st)) cu++;
  82.             if (B[i] % 3 == 1) v[cc + B[i] / 3] = cu;
  83.             else v[cy + B[i] / 3] = cu;
  84.         }
  85.         if (sa.size() < v.size()) sa.resize(v.size());
  86.         if (cu == cx) for (int i = 0; i < cx; i++) sa[v[i + nx] - 1 + nx] = i;
  87.         else buildSA(nx, cu);
  88.         A.clear();
  89.         if (n % 3 == 1) A.pb(n - 1);
  90.         for (int i = 0; i < cx; i++) if (sa[i + nx] < c1) A.pb(sa[i + nx] * 3);
  91.         startPoss.clear(), startPoss.resize(n + 1, 0);
  92.         startPoss[n] = -1;
  93.         for (int i = 0; i < cx; i++) {
  94.             if (sa[i + nx] < c1) sa[i + nx] = sa[i + nx] * 3 + 1;
  95.             else sa[i + nx] = (sa[i + nx] - c1) * 3 + 2;
  96.             startPoss[sa[i + nx]] = i;
  97.         }
  98.         rsort(A, B, st, mx, c0);
  99.         function<bool(int, int)> cmp = [&](int x, int y) -> bool {
  100.             if (v[x + st] != v[y + st]) return v[x + st] < v[y + st];
  101.             if (x % 3 == 2) return cmp(x + 1, y + 1);
  102.             return startPoss[x + 1] < startPoss[y + 1];
  103.         };
  104.         cu = st;
  105.         for (int i = 0, j = 0; i < cx || j < c0;) {
  106.             if (i == cx) sa[cu++] = B[j++];
  107.             else if (j == c0) sa[cu++] = sa[i + nx], i++;
  108.             else if (cmp(sa[i + nx], B[j])) sa[cu++] = sa[i + nx], i++;
  109.             else sa[cu++] = B[j++];
  110.         }
  111.     }
  112.     void LCPcalc() {
  113.         startPoss.resize(len + 1), lcp.resize(len + 1);
  114.         for (int i = 0; i <= len; i++) startPoss[sa[i]] = i;
  115.         int tp = 0;
  116.         for (int i = 0; i < len; i++) {
  117.             if (tp) tp--;
  118.             while (v[sa[startPoss[i] - 1] + tp] == v[i + tp]) tp++;
  119.             lcp[startPoss[i]] = tp;
  120.         }
  121.     }
  122.     void init(VC& _init) {
  123.         len = _init.size();
  124.         v.clear();
  125.         for (auto u : _init) v.pb(static_cast<int>(u));
  126.         int mx = 0;
  127.         for (int i = 0; i < v.size(); i++) {
  128.             v[i] ++;
  129.             if (v[i] > mx) mx = v[i];
  130.         }
  131.         v.pb(0);
  132.         buildSA(0, mx + 1);
  133.         A.clear(), B.clear(), cnt.clear();
  134.         sa.resize(len + 1);
  135.         LCPcalc();
  136.         wnt.init(lcp);
  137.         v.clear();
  138.     };
  139.     int getLCP(int x, int y) {
  140.         if (x == y) return len - x;
  141.         x = startPoss[x] + 1, y = startPoss[y] + 1;
  142.         if (x > y) swap(x, y);
  143.         return wnt.get(x, y);
  144.     }
  145.     VI Gsa() { auto it = sa; sa.clear(); return it; }
  146.     VI Gla() { auto it = lcp; lcp.clear(); return it; }
  147. } sa;
  148. struct Node {
  149.     bool sp = false;
  150.     VI chd;
  151.     VB data;
  152.     Node() {
  153.         sp = false;
  154.         chd.clear();
  155.         data.clear();
  156.     }
  157. };
  158. vector<Node> nds;
  159. int get(int u, int startPoss) { return u >> (7 - startPoss) & 1; }
  160. void output(VB& outdata, int val, int len) { FOR(i,0,len) outdata.pb(val >> (len - 1 - i) & 1); }
  161. void output(VB& outdata, bool val) { output(outdata, val, 1); }
  162. VB bufVec, his;
  163. bool inputOneBit() { bool ret = bufVec.back(); bufVec.pop_back(); his.pb(ret); return ret; }
  164. int input(int len = 1) { int ret = 0; FOR(i,0,len) ret = ret << 1 | inputOneBit(); return ret; }
  165. void insertBuf(VB tp) { reverse(all(tp)); for (auto v : tp) bufVec.pb(v); }
  166. BS buffData;
  167. unsigned char tmpchar[1 << 22];
  168. struct state {
  169.     int curVal;
  170.     char curOperator;
  171.     int startPos;
  172.     int lastPos;
  173.     state(int cv = 1e9, char cu = 0, int sp = 0, int lp = 0) : curVal(cv), curOperator(cu), startPos(sp), lastPos(lp) {}
  174.     bool operator<(const state& A) {
  175.         return curVal < A.curVal;
  176.     }
  177. };
  178. struct bit {
  179.     vector<state> v;
  180.     int n;
  181.     void init(int m) {
  182.         n = m + 1;
  183.         v.resize(n);
  184.     }
  185.     state get(int k) {
  186.         k = n - k;
  187.         state ret = state();
  188.         while (k) {
  189.             if (v[k] < ret) ret = v[k];
  190.             k -= k & -k;
  191.         }
  192.         return ret;
  193.     };
  194.     void upd(int k, state x) {
  195.         k = n - k;
  196.         while (k <= n) {
  197.             if (x < v[k]) v[k] = x;
  198.             k += k & -k;
  199.         }
  200.     };
  201. }bt[2];
  202. map<HS, int> mp;
  203. int dfs(CD rt) {
  204.     if (mp.count(rt.get()->get_hash())) return mp[rt.get()->get_hash()];
  205.     int cz = nds.size();
  206.     mp[rt.get()->get_hash()] = cz;
  207.     nds.pb(Node());
  208.     CS cs = vm::load_cell_slice_special(rt, nds[cz].sp);
  209.     for (int i = 0; i < sz(cs); i++) nds[cz].data.pb(cs.data_bits()[i]);
  210.     CB cb;
  211.     cb.append_cellslice(cs);
  212.     for (int i = 0; i < cb.get_refs_cnt(); i++) {
  213.         int tp = dfs(cb.get_ref(i));
  214.         nds[cz].chd.pb(tp);
  215.     }
  216.     return cz;
  217. }
  218. const int MAXN = 1024;
  219. const int hCNT = 2;
  220. int constant[hCNT][MAXN] = { {1141,1118,1706,504,91,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},{0,1520,891,325,262,123,124,87,93,47,69,39,53,36,44,30,36,19,29,17,19,25,26,15,11,16,18,7,17,8,9,7,12,9,6,8,10,8,5,4,5,4,6,7,4,1,7,2,5,3,8,6,4,4,6,2,1,5,3,5,2,1,2,5,378,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, };
  221. VB coding[hCNT][MAXN * 3];
  222. vector<vector<VI>> chd(hCNT, vector<VI>(MAXN, VI()));
  223. void huffmanBuild() {
  224.     for (int pp = 0; pp < hCNT; pp++) {
  225.         set<pair<int, int>> st;
  226.         for (int i = 0; i < MAXN; i++) st.insert({ constant[pp][i], i });
  227.         while (st.size() > 1) {
  228.             auto x = *st.begin();
  229.             st.erase(st.begin());
  230.             auto y = *st.begin();
  231.             st.erase(st.begin());
  232.             chd[pp].push_back(VI(0));
  233.             chd[pp].back().push_back(abs(x.second)), chd[pp].back().push_back(abs(y.second));
  234.             st.emplace(x.first + y.first, chd[pp].size() - 1);
  235.         }
  236.         for (int i = 0; i < chd[pp].size(); i++) coding[pp][i].clear();
  237.         for (int i = chd[pp].size() - 1; i >= MAXN; i--) {
  238.             for (int j = 0; j < chd[pp][i].size(); j++) {
  239.                 int u = chd[pp][i][j];
  240.                 coding[pp][u] = coding[pp][i];
  241.                 coding[pp][u].push_back(j);
  242.             }
  243.         }
  244.     }
  245. }
  246. int hufR(int tx) {
  247.     int p = MAXN * 2 - 2;
  248.     while (p >= MAXN) p = chd[tx][p][input()];
  249.     return p;
  250. }
  251. void hufW(VB& ret, int tx, int val) {
  252.     for (auto u : coding[tx][val]) output(ret, u);
  253. }
  254.  
  255. BS compress(BS& data) {
  256.     buffData = data.copy();
  257.     CD root = vm::std_boc_deserialize(buffData).move_as_ok();
  258.     nds.clear();
  259.     dfs(root);
  260.     int N = nds.size();
  261.     auto xx = nds;
  262.     VI id(N), _id(N);
  263.     FOR(i, 0, N) id[i] = i;
  264.     int exN = 0;
  265.     for (int i = 0; i < N; i++) exN += nds[i].sp;
  266.     sort(all(id), [&](int x, int y) {
  267.         if (nds[x].sp != nds[y].sp) return nds[x].sp > nds[y].sp;
  268.         if (nds[x].data.size() != nds[y].data.size()) return nds[x].data.size() < nds[y].data.size();
  269.         for (int j = 0; j < min(nds[x].data.size(), nds[y].data.size()); j++) {
  270.             if (nds[x].data[j] > nds[y].data[j]) return true;
  271.             if (nds[x].data[j] < nds[y].data[j]) return false;
  272.         }
  273.         return x < y;
  274.         });
  275.     FOR(i, 0, N) _id[id[i]] = i;
  276.     VB ret(0);
  277.     int l = 0;
  278.     while ((1 << l) < N) l++;
  279.     output(ret, l, 8);
  280.     output(ret, N, l);
  281.     output(ret, exN, l);
  282.     output(ret, _id[0], l);
  283.     FOR(i, 0, N) nds[i] = xx[id[i]];
  284.     xx.clear();
  285.     FOR(i, 0, N) for (auto& x : nds[i].chd) x = _id[x];
  286.     VP tt;
  287.     VI an(100);
  288.     FOR(i, 0, exN) {
  289.         int t = 0;
  290.         for (int j = 0; j < 8; j++) t = t << 1 | nds[i].data[j];
  291.         an[t] ++;
  292.     }
  293.     FOR(i, 1, 5) output(ret, an[i], l);
  294.     VP gas, gg;
  295.     for (int i = exN; i < N; i++) {
  296.         int x = nds[i].chd.size();
  297.         if (!gas.empty() && gas.back().first == x && gas.back().second + 1 < 1024) gas.back().second++;
  298.         else gas.emplace_back(x, 1);
  299.     }
  300.     for (auto [u, v] : gas) hufW(ret, 0, u), hufW(ret, 1, v);
  301.     cerr << ret.size() << endl;
  302.     VP tmp;
  303.     for (int i = exN; i < N; i++) {
  304.         int x = nds[i].data.size();
  305.         if (!tmp.empty() && tmp.back().first == x) tmp.back().second++;
  306.         else tmp.pb(x, 1);
  307.     }
  308.     for (auto [x, y] : tmp) {
  309.         output(ret, x, 10);
  310.         output(ret, y, 13);
  311.     }
  312.     cerr << ret.size() << endl;
  313.     FOR(i, 0, N) for (auto u : nds[i].chd) output(ret, u, l);
  314.     cerr << ret.size() << endl;
  315.  
  316.     FOR(i, 0, exN) {
  317.         int lcp = 0;
  318.         while (i && lcp < nds[i].data.size() && lcp < nds[i - 1].data.size() && lcp + 1 < 16 && nds[i].data[lcp] == nds[i - 1].data[lcp]) lcp++;
  319.         output(ret, lcp, 4);
  320.         for (int j = lcp; j < nds[i].data.size(); j++) output(ret, nds[i].data[j]);
  321.     }
  322.     cerr << ret.size() << endl;
  323.     VC tempVec;
  324.     for (int i = exN; i < N; i++) for (auto u : nds[i].data) tempVec.pb(u);
  325.     sa.init(tempVec);
  326.     auto lcp = sa.Gla();
  327.     auto sa_id = sa.Gsa();
  328.     int n = tempVec.size();
  329.     vector<state> dp(n + 1);
  330.     dp[0].curVal = 0;
  331.     VI _sa_id(n);
  332.     for (int i = 1; i <= n; i++) _sa_id[sa_id[i]] = i;
  333.     auto write = [&](int u, int len) {
  334.         for (int i = 0; i < len; i++) ret.pb(u >> (len - 1 - i) & 1);
  335.     };
  336.     VS firstID(n), secondID(n);
  337.     int curID = exN, sum = 0;
  338.     for (int i = 0; i < n; i++) {
  339.         while (curID < N && sum + nds[curID].data.size() <= i) sum += nds[curID++].data.size();
  340.         firstID[i] = curID;
  341.         secondID[i] = i - sum;
  342.     }
  343.     int m = __lg(n);
  344.     int inf = 1e9;
  345.     bt[0].init(n + 1); bt[1].init(n + 1);
  346.     for (int i = 0; i <= n; i++) {
  347.         if (i) {
  348.             dp[i] = bt[1].get(i);
  349.             auto xx = bt[0].get(i);
  350.             xx.curVal += i;
  351.             if (xx < dp[i]) dp[i] = xx;
  352.         }
  353.         if (i == n) break;
  354.         state cst = { dp[i].curVal + 8 - i , 0, i, i };
  355.         bt[0].upd(min(n, i + 128), cst);
  356.         int val = 0, startPoss = 0;
  357.         int mn = inf;
  358.         for (int j = _sa_id[i] - 1; j >= max(1, _sa_id[i] - 30); j--) {
  359.             mn = min(mn, lcp[j + 1]);
  360.             if (sa_id[j] < i) {
  361.                 val = mn;
  362.                 startPoss = i - sa_id[j];
  363.                 break;
  364.             }
  365.         }
  366.         mn = inf;
  367.         for (int j = _sa_id[i] + 1; j <= min(_sa_id[i] + 30, n); j++) {
  368.             mn = min(mn, lcp[j]);
  369.             if (sa_id[j] < i && mn > val) {
  370.                 val = mn;
  371.                 startPoss = i - sa_id[j];
  372.                 break;
  373.             }
  374.         }
  375.         val = min(val, 1 << 9);
  376.         int cans = 12 + m;
  377.         char tp = 2;
  378.         cst = { dp[i].curVal + cans, tp, startPoss, i };
  379.         bt[1].upd(i + val, cst);
  380.         int id = firstID[i];
  381.         int p = i;
  382.         if (!secondID[i] || i % 3 == 1) for (int ii = 0; ii < 3; ii++) {
  383.             if (id - ii - 1 < exN || nds[id - ii - 1].data.size() == 0) break;
  384.             p -= nds[id - ii - 1].data.size();
  385.             int len = min(128, sa.getLCP(i, p));
  386.             int cans = 7;
  387.             char tp;
  388.             if (!ii) cans += 2, tp = 1;
  389.             else {
  390.                 cans += (ii + 3); tp = ii + 2;
  391.                 if (ii == 2) cans--;
  392.             }
  393.             cst = { dp[i].curVal + cans, tp, 0, i };
  394.             bt[1].upd(i + len, cst);
  395.         }
  396.     }
  397.     vector<tuple<int, int, int>> ttt;
  398.     int p = n, mx = 0;
  399.     while (p) {
  400.         ttt.pb(dp[p].curOperator, p - dp[p].lastPos, dp[p].startPos);
  401.         if (dp[p].curOperator == 2) mx = max(mx, dp[p].startPos);
  402.         p = dp[p].lastPos;
  403.     }
  404.     reverse(all(ttt));
  405.     int MM = 0;
  406.     while ((1 << MM) <= mx) MM++;
  407.     write(MM, 5);
  408.     for (auto [x, y, z] : ttt) {
  409.         for (int p = 0; p < 5; p++) {
  410.             if (p == x) {
  411.                 if (p != 4) write(1, 1);
  412.                 if (!p) {
  413.                     write(y - 1, 7);
  414.                     for (int i = z; i < z + y; i++) ret.pb(tempVec[i]);
  415.                 }
  416.                 else if (p == 2) write(y - 1, 9), write(z, MM);
  417.                 else write(y - 1, 7);
  418.                 break;
  419.             }
  420.             else write(0, 1);
  421.         }
  422.     }
  423.     while (ret.size() % 8) ret.pb(0);
  424.     for (int i = 0; i < ret.size(); i += 8) {
  425.         tmpchar[i] = 0;
  426.         for (int j = 0; j < 8; j++) tmpchar[i / 8] = tmpchar[i / 8] << 1 | ret[i + j];
  427.     }
  428.     cerr << ret.size() << endl;
  429.     buffData = BS(td::Slice(tmpchar, ret.size() / 8));
  430.     return td::lz4_compress(buffData);
  431. }
  432.  
  433. BS decompress(BS& data) {
  434.     cerr << "here\n";
  435.     buffData = td::lz4_decompress(data, 2 << 20).move_as_ok();
  436.     VB tempVec(0);
  437.     FOR(i,0,buffData.length()) FOR(j,0,8) tempVec.pb(get(buffData[i], j));
  438.     insertBuf(tempVec);
  439.     int l = input(8);
  440.     int N = input(l);
  441.     nds.clear(), nds.resize(N);
  442.     int exN = input(l);
  443.     int root = input(l);
  444.     VI an(100);
  445.     FOR(i,1,5) an[i] = input(l);
  446.     VI len(N), chdsz(N);
  447.     for (int i = 0; i < exN; i++) {
  448.         if (i < an[2]) len[i] = 264, chdsz[i] = 0;
  449.         else if (i < an[2] + an[3]) len[i] = 280, chdsz[i] = 1;
  450.         else if (i < an[1] + an[2] + an[3]) len[i] = 288, chdsz[i] = 0;
  451.         else len[i] = 552, chdsz[i] = 2;
  452.     }
  453.  
  454.     int curstartPosinter = exN;
  455.     while (curstartPosinter < N) {
  456.         int x = hufR(0);
  457.         int y = hufR(1);
  458.         while (y--) chdsz[curstartPosinter++] = x;
  459.     }
  460.     curstartPosinter = exN;
  461.     while (curstartPosinter < N) {
  462.         int x = input(10);
  463.         int lx = input(13);
  464.         while (lx--) len[curstartPosinter++] = x;
  465.     }
  466.     for (int i = 0; i < exN; i++) nds[i].sp = true;
  467.     for (int i = 0; i < N; i++) for (int j = 0; j < chdsz[i]; j++) nds[i].chd.pb(input(l));
  468.  
  469.     VI lastPP(N);
  470.     for (int i = 0; i < exN; i++) {
  471.         int lcp = input(4);
  472.         VB tmp;
  473.         for (int j = 0; j < lcp; j++) tmp.pb(his[lastPP[i - 1] + j]);
  474.         insertBuf(tmp);
  475.         lastPP[i] = his.size();
  476.         while (nds[i].data.size() < len[i]) nds[i].data.pb(input());
  477.     }
  478.     int MM = input(5);
  479.     int curID = exN, sum = 0, tempSum = 0;
  480.     for (int i = exN; i < N; i++) tempSum += len[i];
  481.     VI firstID(tempSum);
  482.     for (int i = 0; i < tempSum; i++) {
  483.         while (curID < N && sum + len[curID] <= i) sum += len[curID++];
  484.         firstID[i] = curID;
  485.     }
  486.     tempVec.clear();
  487.     while (tempVec.size() < tempSum) {
  488.         int zcnt = 0;
  489.         while (!input()) if (++zcnt == 4) break;
  490.         if (!zcnt) {
  491.             int len = input(7) + 1;
  492.             for (int i = 0; i < len; i++) tempVec.pb(input());
  493.         }
  494.         else if (zcnt ==2) {
  495.             int len = input(9) + 1;
  496.             int st = input(MM);
  497.             for (int i = 0; i < len; i++) tempVec.pb(tempVec[tempVec.size() - st]);
  498.         }
  499.         else {
  500.             if (zcnt == 1) zcnt--;
  501.             else zcnt -= 2;
  502.             int lx = input(7) + 1;
  503.             int tmpSum = 0;
  504.             for (int i = 0; i <= zcnt; i++) tmpSum += len[firstID[tempVec.size()] - 1 - i];
  505.             for (int i = 0; i < lx; i++) tempVec.pb(tempVec[tempVec.size() - tmpSum]);
  506.         }
  507.     }
  508.  
  509.     reverse(all(tempVec));
  510.     for (int i = exN; i < N; i++) for (int j = 0; j < len[i]; j++) nds[i].data.pb(tempVec.back()), tempVec.pop_back();
  511.     vector<CD> cells(N);
  512.     VB vis(N, 0);
  513.     auto _dfs = [&](auto self, int i) {
  514.         if (vis[i]) return;
  515.         vis[i] = 1;
  516.         CB cb;
  517.         for (auto u : nds[i].chd) {
  518.             self(self, u);
  519.             cb.store_ref(cells[u]);
  520.         }
  521.         for (auto u : nds[i].data) cb.store_bool_bool(u);
  522.         cells[i] = cb.finalize(nds[i].sp);
  523.     };
  524.     _dfs(_dfs, root);
  525.     buffData = vm::std_boc_serialize(cells[root], 31).move_as_ok();
  526.     return buffData.copy();
  527. }
  528.  
  529. int main() {
  530.     ios::sync_with_stdio(0);
  531.     cin.tie(0), cout.tie(0);
  532.     string mode;
  533.     cin >> mode;
  534.     CHECK(mode == "compress" || mode == "decompress");
  535.  
  536.     string base64_data;
  537.     cin >> base64_data;
  538.     CHECK(!base64_data.empty());
  539.     BS data(td::base64_decode(base64_data).move_as_ok());
  540.     huffmanBuild();
  541.     if (mode == "compress") {
  542.         data = compress(data);
  543.     }
  544.     else {
  545.         data = decompress(data);
  546.     }
  547.  
  548.     cout << td::base64_encode(data) << endl;
  549.     return 0;
  550. }
  551.  
  552.  
Add Comment
Please, Sign In to add comment