제출 #1052726

#제출 시각아이디문제언어결과실행 시간메모리
1052726amirhoseinfar1385모임들 (IOI18_meetings)C++14
60 / 100
3003 ms786432 KiB
#include "meetings.h"
#include<bits/stdc++.h>
using namespace std;
const int maxn=750000+10,lg=20,kaf=(1<<lg),maxr=maxn;
long long ezaf=0,n,all[maxn],dpl[maxn],dpr[maxn],psl[maxn],psr[maxn],inf=1e16,ezafq[maxn];
int tr[maxn],tl[maxn];
vector<pair<int,int>>allql[maxn],allqr[maxn];
long long q,res[maxn];
struct func{
  long long y0;
  int x0,sh;
  func(){
    x0=0;
    y0=inf;
    sh=0;
  }
  long long get(int x){
    return 1ll*(x-x0)*sh+y0;
  }
}fakefunc;
 
struct lichao{
  struct node{
    func f;
    int cl,cr;
    node(){
      cl=cr=-1;
    }
  }fakenode;
  vector<node>alln;
  int te=1;
  lichao(){
    te=1;
    alln.resize(1);
  }
  void clear(){
    for(int i=0;i<te;i++){
      alln[i]=fakenode;
    }
    te=1;
  }
  int getl(int i){
    if(alln[i].cl==-1){
      if((int)alln.size()==te){
        alln.push_back(fakenode);
      }
      alln[i].cl=te;
      te++;
    }
    return alln[i].cl;
  }
  int getr(int i){
    if(alln[i].cr==-1){
      if((int)alln.size()==te){
        alln.push_back(fakenode);
      }
      alln[i].cr=te;
      te++;
    }
    return alln[i].cr;
  }
  long long pors(int i,int l,int r,int x){
    if(i==-1){
      return inf;
    }
    long long ret=alln[i].f.get(x);
    int mid=(l+r)>>1;
    if(r==l+1){
      return ret;
    }
    if(x<mid){
      ret=min(ret,pors(alln[i].cl,l,mid,x));
    }else{
      ret=min(ret,pors(alln[i].cr,mid,r,x));
    }
    return ret;
  }
  void ins(int i,int l,int r,func fa){
    if(alln[i].f.sh==0){
       swap(alln[i].f,fa);
       return ;
    }
    if(alln[i].f.get(l)>fa.get(l)){
      swap(alln[i].f,fa);
    }
    if(r==l+1){
      return ;
    } 
    int mid=(l+r)>>1;
    if(alln[i].f.get(mid)<=fa.get(mid)){
      return ins(getr(i),mid,r,fa);
    }else{
      swap(alln[i].f,fa);
      return ins(getl(i),l,mid,fa);
    }
  }
}lch;

bool cmp(pair<int,func>a,pair<int,func>b){
  if(a.first!=b.first){
    return a.first<b.first;
  }
  if(a.second.x0!=b.second.x0){
    return a.second.x0<b.second.x0;
  }  
  if(a.second.sh!=b.second.sh){
    return a.second.sh<b.second.sh;
  }
  return a.second.y0<b.second.y0;
}
 
struct segment{
  vector<pair<int,pair<int,int>>>segq[(1<<(lg+1))];
  vector<pair<int,func>>segi[(1<<(lg+1))];
  void clear(){
    for(int i=0;i<(1<<(lg+1));i++){
      segq[i].clear();
      segi[i].clear();
    }
  }
  void insq(int i,pair<int,pair<int ,int>>w){
    i+=kaf;
    while(i>0){
      segq[i].push_back(w);
      i>>=1;
    }
  }
  void insi(int i,int l,int r,int tl,int tr,pair<int,func>w){
    if(l>r||l>tr||r<tl||tl>tr){
      return ;
    }
    if(l>=tl&&r<=tr){
      segi[i].push_back(w);
      return ;
    }
    int m=(l+r)>>1;
    insi((i<<1),l,m,tl,tr,w);
    insi((i<<1)^1,m+1,r,tl,tr,w);
    return ;
  }
  void calc(int w){
    lichao lich;
    for(int i=0;i<(1<<(lg+1));i++){
      sort(segq[i].begin(),segq[i].end());
      sort(segi[i].begin(),segi[i].end(),cmp);
      lich.clear();
      if(w==0){
        int i1=(int)segq[i].size()-1,i2=(int)segi[i].size()-1;
        while(i1>=0&&i2>=0){
          if(segq[i][i1].first<=segi[i][i2].first){
            lich.ins(0,0,maxr-1,segi[i][i2].second);
            i2--;
          }else{
            res[segq[i][i1].second.second]=min(res[segq[i][i1].second.second],lich.pors(0,0,maxr,segq[i][i1].second.first)+ezafq[segq[i][i1].second.second]);
            i1--;
          }
        }
        while(i1>=0){
           res[segq[i][i1].second.second]=min(res[segq[i][i1].second.second],lich.pors(0,0,maxr,segq[i][i1].second.first)+ezafq[segq[i][i1].second.second]);
           i1--;
        }
      }else{
        int i1=0,i2=0;
        while(i1<(int)segq[i].size()&&i2<(int)segi[i].size()){
          if(segq[i][i1].first>=segi[i][i2].first){
            lich.ins(0,0,maxr-1,segi[i][i2].second);
            i2++;
          }else{
            res[segq[i][i1].second.second]=min(res[segq[i][i1].second.second],lich.pors(0,0,maxr,segq[i][i1].second.first)+ezafq[segq[i][i1].second.second]);
            i1++;
          }
        }
        while(i1<(int)segq[i].size()){
           res[segq[i][i1].second.second]=min(res[segq[i][i1].second.second],lich.pors(0,0,maxr,segq[i][i1].second.first)+ezafq[segq[i][i1].second.second]);
           i1++;
        }
      }
    }
  }
}seg;
 
void caltltr(){
  vector<int>v;
  all[0]=1e9+5;
  all[n+1]=1e9+5;
  v.push_back(0);
  for(int i=1;i<=n+1;i++){
    while((int)v.size()>1&&all[v.back()]<=all[i]){
      tr[v.back()]=i;
      v.pop_back();
    }
    v.push_back(i);
  }
  v.clear();
  v.push_back(n+1);
  for(int i=n;i>=0;i--){
    while((int)v.size()>1&&all[v.back()]<all[i]){
      tl[v.back()]=i;
      v.pop_back();
    }
    v.push_back(i);
  }
}
 
void solvel(){
  vector<int>v;
  v.push_back(0);
  for(int i=1;i<=n;i++){
    dpl[i]=inf;
    while(all[v.back()]<=all[i]){
      dpl[i]=min(dpl[i],dpl[v.back()]+(i-v.back()-1)*all[v.back()]);
      v.pop_back();
    }
    v.push_back(i);
    if(tl[i]==i-1){
      dpl[i]=psl[i]=psl[tl[i]]+all[i];
    }else{
      dpl[i]+=all[i];
    }
    psl[i]=psl[tl[i]]+(i-tl[i])*all[i];
    func fa;
    fa.x0=i;
    fa.y0=dpl[i];
    fa.sh=all[i];
    seg.insi(1,0,kaf-1,i,tr[i]-1,make_pair(i,fa));
    for(auto x:allqr[i]){
      int p=lower_bound(v.begin(),v.end(),x.first)-v.begin();
      int now=i;
      now=v[p];
      long long manf=psl[tl[now]]+(x.first-1-tl[now])*all[now];
      ezafq[x.second]=-manf;
      seg.insq(i,make_pair(now+1,make_pair(i,x.second)));
    }
  }
  seg.calc(0);
  seg.clear();
}
 
void solver(){
  vector<int>v;
  deque<int>tofv;
  seg.clear();
  v.push_back(n+1);
  tofv.push_front(n+1);
  for(int i=n;i>=1;i--){
    dpr[i]=inf;
    while(all[v.back()]<all[i]){
      dpr[i]=min(dpr[i],dpr[v.back()]+(v.back()-i-1)*all[v.back()]);
      v.pop_back();
      tofv.pop_front();
    }
    tofv.push_front(i);
    v.push_back(i);
    if(tr[i]==i+1){
      dpr[i]=psr[i]=psr[tr[i]]+all[i];
    }else{
      dpr[i]+=all[i];
    }
    psr[i]=psr[tr[i]]+(tr[i]-i)*all[i];
    func fa;
    fa.x0=i;
    fa.y0=dpr[i];
    fa.sh=-all[i];
    seg.insi(1,0,kaf-1,tl[i]+1,i,make_pair(i,fa));
    for(auto x:allql[i]){
      int p=lower_bound(tofv.begin(),tofv.end(),x.first+1)-tofv.begin();
      int now=i;
      if(p==0||p-1>=(int)tofv.size()){
        continue;
      }
      now=tofv[p-1];
      long long manf=psr[tr[now]]+(tr[now]-x.first-1)*all[now];
      ezafq[x.second]=-manf;
      seg.insq(i,make_pair(now-1,make_pair(i,x.second)));
    }
  }
  seg.calc(1);
}
 
std::vector<long long> minimum_costs(std::vector<int> H, std::vector<int> L,
                                     std::vector<int> R) {
  n=H.size();
  for(int i=1;i<=n;i++){
    all[i]=H[i-1];
  }
  q=(int)L.size();
  for(int i=0;i<q;i++){
    L[i]++;
    R[i]++;
    res[i]=inf;
    allql[L[i]].push_back(make_pair(R[i],i));
    allqr[R[i]].push_back(make_pair(L[i],i));
  }
  caltltr();
  solvel();
  solver();
  vector<long long>ret;
  for(int i=0;i<q;i++){
    if(L[i]==R[i]){
      res[i]=all[L[i]];
    }
    ret.push_back(res[i]);
  }
  return ret;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...