Submission #1035472

#TimeUsernameProblemLanguageResultExecution timeMemory
1035472amirhoseinfar1385Meetings (IOI18_meetings)C++17
0 / 100
450 ms786432 KiB
#include "meetings.h"
#include<bits/stdc++.h>
using namespace std;
const long long maxn=750000+10,lg=20,kaf=(1<<lg),maxr=1e9+5;
long long ezaf=0,all[maxn],n,dpl[maxn],dpr[maxn],tr[maxn],tl[maxn],psl[maxn],psr[maxn],inf=1e16;
vector<pair<long long,long long>>allql[maxn],allqr[maxn];
long long q,res[maxn];
struct func{
  long long x0,y0,sh,ta,w,tb,wb;
  func(){
    x0=0;
    y0=inf;
    sh=0;
    ta=inf;
    tb=-inf;
    wb=-inf;
    w=inf;
  }
  long long get(long long x){
  //  if(x>=ta){
  //    return w;
  //  }
  //  if(x<=tb){
  //    return wb;
  //  }
 //   cout<<"wtf: "<<(x-x0)*sh+y0<<" "<<x0<<" "<<y0<<" "<<sh<<" "<<x<<endl;
    return (x-x0)*sh+y0;
  }
}fakefunc;

struct lichao{
  struct node{
    func f;
    long long cl,cr;
    node(){
      cl=cr=-1;
    }
  }fakenode;
  vector<node>alln;
  long long te=1;
  vector<vector<pair<int,func>>>bar;
  lichao(){
    te=1;
    bar.push_back({});
    alln.resize(1);
  }
  void back(){
  //  cout<<"wtf: "<<(int)bar.size()<<endl;
    bar.pop_back();
    for(auto x:bar.back()){
      alln[x.first].f=x.second;
    }
    bar.pop_back();
    bar.push_back({});
//    cout<<"khor: "<<(int)bar.size()<<endl;
  }
  long long getl(long long i){
    if(alln[i].cl==-1){
      alln.push_back(fakenode);
      alln[i].cl=te;
      te++;
    }
    return alln[i].cl;
  }
  long long getr(long long i){
    if(alln[i].cr==-1){
      alln.push_back(fakenode);
      alln[i].cr=te;
      te++;
    }
    return alln[i].cr;
  }
  long long pors(long long i,long long l,long long r,long long x){
    if(i==-1){
      return inf;
    }
   // cout<<"pors: "<<i<<" "<<l<<" "<<r<<" "<<alln[i].f.get(x)<<" "<<alln[i].f.sh<<"\n";
    long long ret=alln[i].f.get(x);
    long long 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(long long i,long long l,long long r,func fa){
    bar.back().push_back(make_pair(i,alln[i].f));
    //if(fa.sh!=0||alln[i].f.sh!=0)
      //cout<<i<<" "<<l<<" "<<r<<" "<<fa.x0<<" "<<fa.sh<<" "<<alln[i].f.get(l)<<" "<<fa.get(l)<<"\n";
    if(alln[i].f.get(l)>fa.get(l)){
      swap(alln[i].f,fa);
    }
    //if(fa.sh!=0||alln[i].f.sh!=0)
    //  cout<<alln[i].f.sh<<endl;
    if(r==l+1){
      bar.push_back({});
      return ;
    } 
    long long 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;

struct segment{
  lichao seg[(1<<(lg+1))];
  void erase(int i){
    i+=kaf;
    while(i>0){
      //seg[i].back();
      i>>=1;
    }
  }
  void ins(long long i,func f){
    i+=kaf;
    while(i>0){
      seg[i].ins(0,0,maxr,f);
      i>>=1;
    }
  }
  long long pors(long long i,long long l,long long r,long long tl,long long tr,long long x){
    if(l>r||l>tr||r<tl||tl>tr){
      return inf;
    }
    if(l>=tl&&r<=tr){
   //   cout<<l<<" "<<r<<" "<<seg[i].pors(1,0,maxr,x)<<endl;
      return seg[i].pors(0,0,maxr,x);
    }
    long long m=(l+r)>>1;
    return min(pors((i<<1),l,m,tl,tr,x),pors((i<<1)^1,m+1,r,tl,tr,x));
  }
}seg;

void caltltr(){
  vector<long long>v;
  all[0]=inf;
  all[n+1]=inf;
  v.push_back(0);
  for(long long i=1;i<=n;i++){
    while(all[v.back()]<all[i]){
      v.pop_back();
    }
    tl[i]=v.back();
    v.push_back(i);
  }
  v.clear();
  v.push_back(n+1);
  for(long long i=n;i>=1;i--){
    while(all[v.back()]<all[i]){
      v.pop_back();
    }
    tr[i]=v.back();
    v.push_back(i);
  }
}

void solvel(){
  vector<long long>v;
  v.push_back(0);
  for(long long i=1;i<=n;i++){
 //   cout<<i<<endl;
    dpl[i]=inf;
    while(all[v.back()]<all[i]){
      dpl[i]=min(dpl[i],dpl[v.back()]+(i-v.back()-1)*all[v.back()]);
      seg.erase(v.size()-1);
      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];
    fa.ta=tr[i];
    fa.w=inf+ezaf;
    fa.tb=i-1;
    fa.wb=-inf-ezaf;
    ezaf++;
    //cout<<"av "<<fa.x0<<" "<<fa.y0<<" "<<fa.sh<<" "<<fa.ta<<" "<<fa.w<<" "<<(int)v.size()-1<<endl;
    seg.ins(v.size()-1,fa);
  //  cout<<"dov"<<endl;
    for(auto x:allqr[i]){
      long long p=lower_bound(v.begin(),v.end(),x.first)-v.begin();
      long long now=i;
      now=v[p];
      long long manf=psl[tl[now]]+(x.first-1-tl[now])*all[now];
      //now=i;
      //while(tl[now]>=x.first){
      //  res[x.second]=min(res[x.second],dpl[now]+(i-now)*all[now]-manf);  
      //  now=tl[now];
     // }
   //   cout<<"wtf: "<<seg.pors(1,0,kaf-1,0,100,i)<<" "<<p<<" "<<v.size()<<endl;
      res[x.second]=min(res[x.second],seg.pors(1,0,kaf-1,p+1,(long long)v.size()-1,i)-manf);
    }
  }
}

void solver(){
  vector<long long>v;
  v.push_back(n+1);
  for(long long 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();
    }
    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];
    for(auto x:allql[i]){
      long long now=i;
      while(tr[now]<=x.first){
        now=tr[now];
      }
      long long manf=psr[tr[now]]+(tr[now]-x.first-1)*all[now];
      now=i;
      while(tr[now]<=x.first){
        res[x.second]=min(res[x.second],dpr[now]+(now-i)*all[now]-manf);  
        now=tr[now];
      }
    }
  }
}

std::vector<long long> minimum_costs(std::vector<int> H, std::vector<int> L,
                                     std::vector<int> R) {
  n=H.size();
  for(long long i=1;i<=n;i++){
    all[i]=H[i-1];
  }
  q=(long long)L.size();
  for(long long 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(long long 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...