Submission #1355770

#TimeUsernameProblemLanguageResultExecution timeMemory
1355770settop모임들 (IOI18_meetings)C++20
41 / 100
1484 ms81068 KiB
#include "meetings.h"
#include<bits/stdc++.h>

using namespace std;
#define ll long long
#define fall(i,a,b) for(int i=a;i<=b;i++)
#define rfall(i,a,b) for(int i=a;i>=b;i--)
#define sz(x) (int) x.size()
#define pb push_back
#define all(x) (int)x.size()
const int MAXN=1e5+10;
const ll inf=1e17;
typedef tuple<int,int,int> trio;
typedef pair<int,int> pii;

int n;
ll dp[MAXN],peso[MAXN],seg[4*MAXN],lz[4*MAXN];
vector<ll>v;
set<int> st[23];

void build(int ind,int l,int r){
  if(l==r){
    seg[ind]=dp[l];
    return;
  }
  int m=(l+r)>>1; build(2*ind,l,m); build(2*ind+1,m+1,r);
  seg[ind]=min(seg[2*ind],seg[2*ind+1]);
}

void unlz(int ind,int l,int r){
  seg[ind]+=lz[ind];
  if(l!=r){
    lz[2*ind]+=lz[ind];
    lz[2*ind+1]+=lz[ind];
  }
  lz[ind]=0;
}

void add(int ind,int l,int r,int a,int b,ll val){
  unlz(ind,l,r);
  if(a>r || l>b) return;
  if(a<=l && b>=r){
    lz[ind]+=val;
    unlz(ind,l,r);
    return;
  }
  int m=(l+r)>>1;
  add(2*ind,l,m,a,b,val); add(2*ind+1,m+1,r,a,b,val);
  seg[ind]=min(seg[2*ind],seg[2*ind+1]);
}

ll query(int ind,int l,int r,int a,int b){
  unlz(ind,l,r);
  if(a>r || l>b) return inf;
  if(a<=l && b>=r)return seg[ind];
  int m=(l+r)>>1;
  return min(query(2*ind,l,m,a,b),query(2*ind+1,m+1,r,a,b));
}

void precalc(){
  ll cur=0;
  stack<int> sta;
  fall(i,0,n-1){
    peso[i]=1;
    cur+=v[i];
    while(sz(sta)){
      auto x=sta.top();
      if(v[x]>v[i]) break;
      cur+=peso[x]*(v[i]-v[x]);
      sta.pop();
      peso[i]+=peso[x];
    }
    dp[i]=cur;
    sta.push(i);
  }
  while(sz(sta))sta.pop();
  cur=0;
  rfall(i,n-1,0){
    peso[i]=1;
    while(sz(sta)){
      auto x=sta.top();
      if(v[x]>v[i]) break;
      cur+=peso[x]*(v[i]-v[x]);
      sta.pop();
      peso[i]+=peso[x];
    }
    dp[i]+=cur;
    sta.push(i);
    cur+=v[i];
  }
  fall(i,0,n-1)
    fall(j,1,v[i]) st[j].insert(i);
  build(1,0,n-1);
}

ll quer(int l,int r){
  vector<trio> to_rem;
  int cur=1;
  while(cur<=20){
    auto it=st[cur].lower_bound(l);
    if(it==st[cur].end() || *it>r) break;
    auto x=*it;
    ll custo=l*v[x]; int at=v[x]+1;
    while(at<=20){
      auto it2=st[at].lower_bound(l);
      if(it2==st[at].begin()) break; 
      it2--;
      custo+=(*it2+1)*(v[*it2]-at+1);
      at=v[*it2]+1;
    }
    int R=r;
    auto it2=st[v[x]+1].upper_bound(x);
    if(it2!=st[v[x]+1].end()) R=min(R,*it2-1); 
    to_rem.pb({x,R,custo});
    cur=v[x]+1;
  }
  cur=1;
  while(cur<=20){
    auto it=st[cur].upper_bound(r);
    if(it==st[cur].begin()) break;
    it--;
    if(*it<l) break;
    auto x=*it;
    ll custo=(n-1-r)*v[x]; int at=v[x]+1;
    while(at<=20){
      auto it2=st[at].upper_bound(r);
      if(it2==st[at].end()) break;
      custo+=(n-*it2)*(v[*it2]-at+1);
      at=v[*it2]+1;
    }
    int L=l;
    auto it2=st[v[x]+1].upper_bound(r);
    if(it2!=st[v[x]+1].begin()){
      it2--;
      L=max(L,*it2+1);
    }
    to_rem.pb({L,x,custo});
    cur=v[x]+1;
  }

  for(auto [a,b,c]:to_rem) add(1,0,n-1,a,b,-c);
  ll ans=query(1,0,n-1,l,r);
  for(auto [a,b,c]:to_rem) add(1,0,n-1,a,b,c);
  return ans;
}

std::vector<long long> minimum_costs(std::vector<int> H, std::vector<int> L,std::vector<int> R) {
    n=sz(H);
    for(auto u:H) v.pb(u);
    precalc();
    vector<ll> ans;
    fall(i,0,sz(L)-1){
      ll x=quer(L[i],R[i]);
      ans.pb(x);
    }
    return ans;
}
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...