Advertisement
ivnikkk

Untitled

May 16th, 2022
74
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.37 KB | None | 0 0
  1. #define _CRT_SECURE_NO_WARNINGS
  2. #include <iostream>
  3. #include <vector>
  4. #include <algorithm>
  5. #include <cmath>
  6. #include <iomanip>
  7. #include <fstream>
  8. #include <string>
  9. #include <set>
  10. #include <deque>
  11. #include <queue>
  12. #include <map>
  13. #include <bitset>
  14. #include <random>
  15. #include <cassert>
  16. #include <unordered_map>
  17. #include <unordered_set>
  18. #include <math.h>
  19. #include <chrono>
  20. #include <ctime>
  21. using namespace std;
  22. using namespace chrono;
  23. #define all(a)            a.begin(), a.end()
  24. #define endl "\n"
  25. typedef long long ll;
  26. typedef long double ld;
  27. ll timer = 0;
  28. mt19937 rnd(chrono::steady_clock::now().time_since_epoch().count());
  29. double gen_rand() {
  30.     ll x = rnd() + 1;
  31.     ll y = rnd() + 1;
  32.     x %= y;
  33.     return x / (double)y;
  34. }
  35. ll stop = 1e4;
  36. ll ans = 1e18;
  37. void break_point(ll& timer) {
  38.     if (timer % stop == 0) {
  39.         if (clock() / (double)CLOCKS_PER_SEC >= 2.8) {
  40.             cout << ans << endl;
  41.             exit(0);
  42.         }
  43.     }
  44. }
  45. vector<vector<vector<ll>>> mas_of_tree;
  46. ll query(ll v, ll tl, ll tr, ll l, ll r, ll x, ll ind_of_tree) {
  47.     timer++;
  48.     break_point(timer);
  49.     if (tr<l || r<tl) {
  50.         return 0;
  51.     }
  52.     if (tl>=l && tr<= r) {
  53.         if (!mas_of_tree[ind_of_tree][v].empty()) {
  54.             ll pos = lower_bound(all(mas_of_tree[ind_of_tree][v]), x) - mas_of_tree[ind_of_tree][v].begin();
  55.             ll pos2 = upper_bound(all(mas_of_tree[ind_of_tree][v]), x) - mas_of_tree[ind_of_tree][v].begin();
  56.             return pos2 - pos;
  57.         }
  58.         else {
  59.             return 0;
  60.         }
  61.     }
  62.     ll tm = (tl + tr) / 2;
  63.     return  query(v * 2, tl, tm, l, r, x, ind_of_tree) + query(v * 2 + 1, tm + 1, tr, l, r, x, ind_of_tree);
  64. }
  65. struct st {
  66.     struct node {
  67.         ll val;
  68.         ll ind;
  69.     };
  70.  
  71.     vector<node> tree;
  72.  
  73.     void seg(ll n, vector<ll>& a) {
  74.         timer++;
  75.         tree.resize(4 * n + 13);
  76.         build(1, 0, n, a);
  77.     }
  78.     void smerge(ll v, ll l, ll r) {
  79.         timer++;
  80.         break_point(timer);
  81.         if (l + 1 == r) {
  82.             return;
  83.         }
  84.         if (tree[2 * v].val < tree[2 * v + 1].val) {
  85.             tree[v].val = tree[2 * v].val;
  86.             tree[v].ind = tree[2 * v].ind;
  87.         }
  88.         else {
  89.             tree[v].val = tree[2 * v + 1].val;
  90.             tree[v].ind = tree[2 * v + 1].ind;
  91.         }
  92.     }
  93.  
  94.     void build(ll v, ll l, ll r, vector<ll>& a) {
  95.         timer++;
  96.         break_point(timer);
  97.         if (l + 1 == r) {
  98.             tree[v].val = a[l];
  99.             tree[v].ind = l;
  100.             return;
  101.         }
  102.         ll m = (l + r) / 2;
  103.         build(2 * v, l, m, a);
  104.         build(2 * v + 1, m, r, a);
  105.         smerge(v, l, r);
  106.     }
  107.     ll getI(ll v, ll l, ll r, ll lq, ll rq, ll add) {
  108.         timer++;
  109.         break_point(timer);
  110.         if (lq >= r || rq <= l) {
  111.             return -1;
  112.         }
  113.         if (l + 1 == r) {
  114.             return (tree[v].val + add < 0 ? tree[v].ind : -1);
  115.         }
  116.         ll m = (l + r) / 2;
  117.         ll ans = -1;
  118.         if (tree[2 * v].val + add < 0 && lq <= m) {
  119.             ans = getI(2 * v, l, m, lq, rq, add);
  120.         }
  121.         if (tree[2 * v + 1].val + add < 0 && lq < r && ans == -1) {
  122.             ans = getI(2 * v + 1, m, r, lq, rq, 0);
  123.         }
  124.         return ans;
  125.     }
  126. };
  127. vector<st> t;
  128. void build(vector<ll>& pref_sum, ll v, ll tl, ll tr, ll ind_of_tree) {
  129.     break_point(timer);
  130.     if (tl == tr) {
  131.         mas_of_tree[ind_of_tree][v] =
  132.             vector<ll>(1, pref_sum[tl]);
  133.         return;
  134.     }
  135.     ll mid = (tl + tr) / 2;
  136.     build(pref_sum, v * 2, tl, mid, ind_of_tree);
  137.     build(pref_sum, v * 2 + 1, mid + 1, tr, ind_of_tree);
  138.     merge(all(mas_of_tree[ind_of_tree][v * 2]), all(mas_of_tree[ind_of_tree][v * 2 + 1]), back_inserter(mas_of_tree[ind_of_tree][v]));
  139.     timer++;
  140. }
  141. ll get(vector<vector<ll>>& cur,vector<ll> &p) {
  142.     ll now = 0;
  143.     ll res = 0;
  144.     bool brek = false;
  145.     for (ll i = 0; i < (ll)cur.size(); i++) {
  146.         timer++;
  147.         break_point(timer);
  148.         ll pos = t[p[i]].getI(1, 0, (ll)cur[i].size(), 0, (ll)cur[i].size(), now);
  149.         if (pos != -1) {
  150.             brek = true;
  151.         }
  152.         else {
  153.             pos = (ll)cur[i].size() - 1;
  154.         }
  155.         res += query(1, 0, (ll)cur[i].size() - 1, 0, pos, -now, p[i]);
  156.         if (brek) {
  157.             break;
  158.         }
  159.         now += cur[i][cur[i].size() - 1];
  160.     }
  161.     return res;
  162. }
  163. signed main() {
  164. #ifdef _DEBUG
  165.     freopen("input.txt", "r", stdin);
  166.     freopen("output.txt", "w", stdout);
  167. #endif
  168.     ios_base::sync_with_stdio(false);
  169.     cin.tie(nullptr);
  170.     cout.tie(nullptr);
  171.     srand(time(NULL));
  172.     ll n;
  173.     cin >> n;
  174.     vector<vector<ll>> a(n);
  175.     mas_of_tree.resize(n);
  176.     t.resize(n);
  177.     for (ll i = 0; i < n; i++) {
  178.         string s;
  179.         cin >> s;
  180.         ll log = 1;
  181.         mas_of_tree[i].resize((ll)s.size() * 4);
  182.         a[i].resize((ll)s.size());
  183.         ll cur = 0;
  184.         for (ll j = 0; j < (ll)a[i].size(); j++) {
  185.             timer++;
  186.             break_point(timer);
  187.             if (s[j] == '(')cur++;
  188.             else cur--;
  189.             a[i][j] = cur;
  190.         }
  191.         build(a[i], 1, 0, (ll)a[i].size() - 1, i);
  192.         t[i].seg((ll)a[i].size(), a[i]);
  193.         timer++;
  194.     }
  195.     double temp = 1000;
  196.     double t0 = 1000;
  197.     vector<ll> main_p(n);
  198.     for (ll i = 0; i < n; i++) {
  199.         main_p[i] = i;
  200.     }
  201.     ll last_res = get(a,main_p);
  202.     ans = last_res;
  203.     ld eps = 1.0 / (double)n;
  204.     while (1) {
  205.         temp = 1000.0;
  206.         while (temp > eps) {
  207.             timer++;
  208.             break_point(timer);
  209.             vector<vector<ll>> sub = a;
  210.             vector<ll> prev_p = main_p;
  211.             for (ll i = 0; i < n * temp / t0; i++) {
  212.                 timer++;
  213.                 break_point(timer);
  214.                 ll k1 = rnd() % n;
  215.                 ll k2 = rnd() % n;
  216.                 swap(sub[k1], sub[k2]);
  217.                 swap(prev_p[k1], prev_p[k2]);
  218.             }
  219.             ll now_res = get(sub, prev_p);
  220.             if (now_res > ans) {
  221.                 ans = now_res;
  222.             }
  223.             timer++;
  224.             break_point(timer);
  225.             double go = exp((now_res - last_res) / temp);
  226.             if (now_res > last_res || gen_rand() <= go) {
  227.                 a = sub;
  228.                 main_p = prev_p;
  229.                 last_res = now_res;
  230.             }
  231.             temp *= 0.995;
  232.         }
  233.     }
  234. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement