Guest User

USACO 2021 Plat Jan P2

a guest
Jan 26th, 2021
574
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.37 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3.  
  4. #define sz(v) (int)v.size()
  5. #define ar array
  6. typedef long long ll;
  7.  
  8. const int MAXN = 2e5+10, MAXL = 19;
  9. const ll INF = 1e18+10;
  10.  
  11. int n, m, q, anc[MAXN][MAXL];
  12. ll a[MAXN], opt[MAXN], pre[MAXN];
  13. vector<int> st;
  14.  
  15. ll sq(ll x){
  16.     return x*x;
  17. }
  18. ll getAns(ll i, int j){ //return ans for row and column, assuming opt[j] and pre[j] is already calculated
  19.     if (j == 0) return a[j]*(i-1);
  20.     if (i < opt[j]){ //deal with this case later
  21.         if (anc[j][0] == -1) return sq(i)*j + getAns(i, 0); //go all the way to the left
  22.         else {
  23.             int c=j;
  24.             for (int k = MAXL-1; k >= 0; k--) if (anc[c][k] != -1 && i < opt[anc[c][k]]) c = anc[c][k];
  25.             c=anc[c][0];
  26.             assert(i >= opt[c]);
  27.  
  28.             return getAns(i, c)+sq(i)*(j-c);
  29.         }
  30. //      return getAns(i, j-1)+sq(i);
  31.     }
  32.     ll ans=0;
  33.     ans += a[j]*(i-opt[j]);
  34.     ans += pre[j];
  35.     return ans;
  36. }
  37. ll getAnsSlow(ll i, int j){ //return ans for row and column, assuming opt[j] andd pre[j-1] is already calculated
  38.     if (j == 0) return a[j]*(i-1);
  39.     ll ans=0;
  40.     ans += (i-opt[j])*a[j];
  41.     ans += sq(opt[j]);
  42.     ans += getAns(opt[j], j-1);
  43.     return ans;
  44. }
  45. void calc(int j){ //calculate ans s.t. you start at (opt[j], j)
  46.  
  47.     while (sz(st) && opt[st.back()] > opt[j]) st.pop_back();
  48.     if (sz(st)) anc[j][0]=st.back();
  49.     else anc[j][0]=-1;
  50.    
  51.     for (int k = 1; k < MAXL; k++) anc[j][k] = (anc[j][k-1] == -1 ? -1 : anc[anc[j][k-1]][k-1]);
  52.     st.push_back(j);
  53.  
  54.     pre[j] = sq(opt[j])+getAns(opt[j], j-1);
  55. }
  56. int main(){
  57.     ios::sync_with_stdio(false); cin.tie(0);
  58.     cin >> n >> m;
  59.     for (int i = 0; i < m; i++) cin >> a[i];
  60.        
  61.     opt[0]=1;
  62.     st.push_back(0);
  63.    
  64.     for (int i = 1; i < m; i++){
  65.        
  66.         auto should_dec = [&](ll j) -> bool {
  67.             if (j == 1) return 0;
  68.             opt[i]=j-1;
  69.             ll nc=getAnsSlow(n, i);
  70.             opt[i]=j;
  71.             ll oc=getAnsSlow(n, i);
  72.             return nc <= oc;
  73.         };
  74.         ll lo=0, hi=n+1, mid=(lo+hi)/2;
  75.         while (lo < mid && mid < hi){
  76.             if (!should_dec(mid)) lo=mid;
  77.             else hi=mid;
  78.             mid=(lo+hi)/2;
  79.         }
  80.         opt[i]=mid;
  81.        
  82.        
  83. //      ll j=n; //turn left at opt[i]
  84. //      while (j > 1){
  85. //          if (should_dec(j)) j--;
  86. //          else break;
  87. //      }
  88. //      opt[i]=j;
  89.        
  90.         calc(i);
  91.     }
  92.  
  93. //  cerr << "opt\n";
  94. //  for (int i = 0; i < n; i++) cerr << opt[i] << ' '; cerr << '\n';
  95.  
  96.     cin >> q;
  97.     while (q--){
  98.         ll i, j; cin >> i >> j, j--;
  99.         cout << getAns(i, j) << '\n';
  100.     }
  101. }
Advertisement
Add Comment
Please, Sign In to add comment