Advertisement
libobil

Untitled

Feb 12th, 2023
697
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.67 KB | None | 0 0
  1. #include <algorithm>
  2. #include <iostream>
  3. #include <numeric>
  4. #include <cassert>
  5. #include <vector>
  6. #include <set>
  7.  
  8. typedef long long llong;
  9. const int MAXN = 1000000 + 10;
  10. const int INF = 2e7 + 10;
  11.  
  12. struct Line
  13. {
  14.     llong x, y;
  15.    
  16.     Line()
  17.     {
  18.         x = -INF;
  19.         y = -INF;
  20.     }
  21.  
  22.     Line(llong _x, llong _y)
  23.     {
  24.         x = _x; y = _y;
  25.     }
  26.  
  27.     inline llong getValue(llong at)
  28.     {
  29.         return x * at + y;
  30.     }
  31.  
  32.     inline friend bool operator < (const Line &a, const Line &b)
  33.     {
  34.         return a.x < b.x;
  35.     }
  36. };
  37.  
  38. inline llong intersect(const Line &prev, const Line &next)
  39. {
  40.     return (prev.y - next.y) / (next.x - prev.x) + ((prev.y - next.y) % (next.x - prev.x) > 0);
  41. }
  42.  
  43. int n, q;
  44. llong g[MAXN];
  45. Line lines[MAXN][2];
  46. Line liChao[2][4*MAXN];
  47. std::vector <std::pair <int,int>> vals[2];
  48. llong output[MAXN];
  49.  
  50. void update(Line tree[], int parity, int l, int r, int node, Line line)
  51. {
  52.     int mid = (l + r) / 2;
  53.     bool atL = tree[node].getValue(vals[parity][l].first) < line.getValue(vals[parity][l].first);
  54.     bool atR = tree[node].getValue(vals[parity][r].first) < line.getValue(vals[parity][r].first);
  55.     bool atMid = tree[node].getValue(vals[parity][mid].first) < line.getValue(vals[parity][mid].first);
  56.    
  57.     if (atL && atR)
  58.     {
  59.         tree[node] = line;
  60.         return;
  61.     }
  62.  
  63.     if (!atL && !atR)
  64.     {
  65.         return;
  66.     }
  67.  
  68.     if (atMid)
  69.     {
  70.         std::swap(tree[node], line);
  71.     }
  72.  
  73.     if (l == r) return;
  74.     if (atL ^ atMid)
  75.     {
  76.         update(tree, parity, l, mid, 2*node, line);
  77.     } else
  78.     {
  79.         update(tree, parity, mid + 1, r, 2*node + 1, line);
  80.     }
  81. }
  82.  
  83. llong query(Line tree[], int parity, int l, int r, int node, int queryPos)
  84. {
  85.     if (tree[node].x == -1) return 0;
  86.     if (l == r)
  87.     {
  88.         return tree[node].getValue(queryPos);
  89.     }
  90.  
  91.     int mid = (l + r) / 2;
  92.     if (queryPos <= vals[parity][mid].first)
  93.     {
  94.         return std::max(tree[node].getValue(queryPos), query(tree, parity, l, mid, 2*node, queryPos));
  95.     } else
  96.     {
  97.         return std::max(tree[node].getValue(queryPos), query(tree, parity, mid + 1, r, 2*node + 1, queryPos));
  98.     }
  99. }
  100.  
  101. void solve()
  102. {
  103.     llong sum = g[1];
  104.     for (int i = 2 ; i <= n ; ++i)
  105.     {
  106.         lines[i][0] = {g[i] + g[i - 1], g[i] * (1 - (i + 1) / 2) - g[i - 1] * (i / 2) + sum};
  107.         lines[i][1] = {g[i] + g[i - 1], g[i] * (1 - i / 2) + g[i - 1] * (1 - (i + 1) / 2) + sum};
  108.         sum += g[i];
  109.     }
  110.  
  111.     for (int j = 0 ; j < 2 ; ++j)
  112.     {
  113.         int ptr = 1;
  114.         std::sort(vals[j].begin(), vals[j].end());
  115.         for (int i = 0 ; i < vals[j].size() ; ++i)
  116.         {
  117.             if (vals[j][i].first == 0 && j)
  118.             {
  119.                 output[vals[j][i].second] = g[1];
  120.                 continue;
  121.             }
  122.  
  123.             while (ptr + 1 <= std::min(n, 2 * vals[j][i].first + j))
  124.             {
  125.                 ptr++;
  126.                 update(liChao[j], j, 0, vals[j].size() - 1, 1, lines[ptr][j]);
  127.             }
  128.  
  129.             output[vals[j][i].second] = query(liChao[j], j, 0, vals[j].size() - 1, 1, vals[j][i].first);
  130.         }
  131.     }
  132.  
  133.     for (int i = 1 ; i <= q ; ++i)
  134.     {
  135.         std::cout << output[i] << '\n';
  136.     }
  137. }
  138.  
  139. void read()
  140. {
  141.     std::cin >> n >> q;
  142.     for (int i = 1 ; i <= n ; ++i)
  143.     {
  144.         std::cin >> g[i];
  145.     }
  146.  
  147.     int pos;
  148.     for (int i = 1 ; i <= q ; ++i)
  149.     {
  150.         std::cin >> pos;
  151.         vals[pos & 1].push_back({pos / 2, i});
  152.     }
  153. }
  154.  
  155. void fastIO()
  156. {
  157.     std::ios_base :: sync_with_stdio(0);
  158.     std::cout.tie(nullptr);
  159.     std::cin.tie(nullptr);
  160. }
  161.  
  162. int main()
  163. {
  164.     fastIO();
  165.     read();
  166.     solve();
  167.  
  168.     return 0;
  169. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement