Guest User

Untitled

a guest
Jul 20th, 2024
189
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.23 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2.  
  3. using i64 = long long;
  4.  
  5. template<class Info>
  6. struct SegmentTree {
  7.     int n;
  8.     std::vector<Info> info;
  9.  
  10.     SegmentTree() : n(0) {}
  11.  
  12.     SegmentTree(int n_, Info v_ = Info()) {
  13.         init(n_, v_);
  14.     }
  15.  
  16.     template<class T>
  17.     SegmentTree(std::vector<T> init_) {
  18.         init(init_);
  19.     }
  20.  
  21.     void init(int n_, Info v_ = Info()) {
  22.         init(std::vector<Info>(n_, v_));
  23.     }
  24.  
  25.     template<class T>
  26.     void init(std::vector<T> init_) {
  27.         n = init_.size();
  28.         int sz = (1 << (std::__lg(n - 1) + 1));
  29.         info.assign(sz * 2, Info());
  30.         std::function<void(int, int, int)> build = [&](int v, int l, int r) {
  31.             if (l == r) {
  32.                 info[v] = init_[l];
  33.                 return;
  34.             }
  35.             int m = (l + r) / 2;
  36.             build(v + v, l, m);
  37.             build(v + v + 1, m + 1, r);
  38.             info[v] = info[v + v] + info[v + v + 1];
  39.         };
  40.         build(1, 0, n - 1);
  41.     }
  42.  
  43.     Info rangeQuery(int v, int l, int r, int tl, int tr) {
  44.         if (r < tl || l > tr) {
  45.             return Info();
  46.         }
  47.         if (l >= tl && r <= tr) {
  48.             return info[v];
  49.         }
  50.         int m = (l + r) / 2;
  51.         return rangeQuery(v + v, l, m, tl, tr) + rangeQuery(v + v + 1, m + 1, r, tl, tr);
  52.     }
  53.  
  54.     Info rangeQuery(int l, int r) {
  55.         return rangeQuery(1, 0, n - 1, l, r);
  56.     }
  57.  
  58.     void modify(int v, int l, int r, int i, const Info &x) {
  59.         if (l == r) {
  60.             info[v] = x;
  61.             return;
  62.         }
  63.         int m = (l + r) / 2;
  64.         if (i <= m) {
  65.             modify(v + v, l, m, i, x);
  66.         } else {
  67.             modify(v + v + 1, m + 1, r, i, x);
  68.         }
  69.         info[v] = info[v + v] + info[v + v + 1];
  70.     }
  71.  
  72.     void modify(int i, const Info &x) {
  73.         modify(1, 0, n - 1, i, x);
  74.     }
  75.  
  76.     Info query(int v, int l, int r, int i) {
  77.         if (l == r) {
  78.             return info[v];
  79.         }
  80.         int m = (l + r) / 2;
  81.         if (i <= m) {
  82.             return query(v + v, l, m, i);
  83.         } else {
  84.             return query(v + v + 1, m + 1, r, i);
  85.         }
  86.     }
  87.  
  88.     Info query(int i) {
  89.         return query(1, 0, n - 1, i);
  90.     }
  91. };
  92.  
  93. struct Max {
  94.     i64 max;
  95.     std::array<int, 3> a;
  96.    
  97.     Max() : max(0) {
  98.         a = {-1, -1, -1};
  99.     }
  100.  
  101.     Max(i64 x, std::array<int, 3> a) : max(x), a(a) {}
  102. };
  103.  
  104. Max operator+(const Max &a, const Max &b) {
  105.     if (a.max > b.max) {
  106.         return a;
  107.     } else {
  108.         return b;
  109.     }
  110. }
  111.  
  112. signed main() {
  113.     int n;
  114.     std::cin >> n;
  115.     std::vector<int> a(n);
  116.     for (int i = 0; i < n; i++) {
  117.         std::cin >> a[i];
  118.     }
  119.     std::vector<std::vector<std::pair<int, int>>> qry(n);
  120.     int q;
  121.     std::cin >> q;
  122.     for (int i = 0; i < q; i++) {
  123.         int l, r;
  124.         std::cin >> l >> r;
  125.         l = n - l;
  126.         r = n - r;
  127.         std::swap(l, r);
  128.         qry[r].emplace_back(l, i);
  129.     }
  130.     std::reverse(a.begin(), a.end());
  131.     std::vector<bool> vis(n + 1);
  132.     std::vector<std::vector<int>> pos(n + 1);
  133.     for (int i = 0; i < n; i++) {
  134.         vis[a[i]] = true;
  135.         pos[a[i]].emplace_back(i);
  136.     }
  137.     std::vector<std::vector<int>> div(n + 1);
  138.     for (int i = 1; i <= n; i++) {
  139.         if (!vis[i]) {
  140.             continue;
  141.         }
  142.         for (int j = i * 2; j <= n; j += i) {
  143.             if (!vis[j]) {
  144.                 continue;
  145.             }
  146.             div[j].emplace_back(i);
  147.         }
  148.     }
  149.     std::vector<std::array<int, 3>> res(q, {-1, -1, -1});
  150.     std::vector<i64> dp(n, 0);
  151.     SegmentTree<Max> st(n);
  152.     for (int i = 0; i < n; i++) {
  153.         int x = a[i];
  154.         for (int y : div[x]) {
  155.             auto it1 = std::lower_bound(pos[y].begin(), pos[y].end(), i);
  156.             if (it1 == pos[y].begin()) {
  157.                 continue;
  158.             }
  159.             it1--;
  160.             int j = *it1;
  161.             for (int z : div[y]) {
  162.                 auto it2 = std::lower_bound(pos[z].begin(), pos[z].end(), j);
  163.                 if (it2 == pos[z].begin()) {
  164.                     continue;
  165.                 }
  166.                 it2--;
  167.                 int k = *it2;
  168.                 i64 val = a[k] + 1LL * n * a[j] + 1LL * n * n * a[i];
  169.                 if (val >= dp[k]) {
  170.                     dp[k] = val;
  171.                     st.modify(k, Max(dp[k], {k, j, i}));
  172.                 }
  173.             }
  174.         }
  175.         for (auto qq : qry[i]) {
  176.             int l = qq.first, r = i, id = qq.second;
  177.             res[id] = st.rangeQuery(l, r).a;
  178.         }
  179.     }
  180.     for (int i = 0; i < q; i++) {
  181.         if (res[i][0] == -1) {
  182.             std::cout << "-1\n";
  183.         } else {
  184.             std::cout << n - res[i][2] << " " << n - res[i][1] << " " << n - res[i][0] << "\n";
  185.         }
  186.     }
  187. }  
Advertisement
Add Comment
Please, Sign In to add comment