結果

問題 No.1467 Selling Cars
ユーザー Taiki0715
提出日時 2025-05-28 22:40:20
言語 C++23
(gcc 13.3.0 + boost 1.87.0)
結果
TLE  
実行時間 -
コード長 21,137 bytes
コンパイル時間 4,501 ms
コンパイル使用メモリ 309,104 KB
実行使用メモリ 16,068 KB
最終ジャッジ日時 2025-05-28 22:40:44
合計ジャッジ時間 22,870 ms
ジャッジサーバーID
(参考情報)
judge3 / judge5
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample -- * 2
other AC * 1 TLE * 3 -- * 27
権限があれば一括ダウンロードができます

ソースコード

diff #

#include <bits/stdc++.h>
using namespace std;
using ll=long long;
using ull=unsigned long long;
using P=pair<ll,ll>;
template<typename T>using minque=priority_queue<T,vector<T>,greater<T>>;
template<typename T>bool chmax(T &a,const T &b){return (a<b?(a=b,true):false);}
template<typename T>bool chmin(T &a,const T &b){return (a>b?(a=b,true):false);}
template<typename T1,typename T2>istream &operator>>(istream &is,pair<T1,T2>&p){is>>p.first>>p.second;return is;}
template<typename T1,typename T2,typename T3>istream &operator>>(istream &is,tuple<T1,T2,T3>&a){is>>std::get<0>(a)>>std::get<1>(a)>>std::get<2>(a);return is;}
template<typename T,size_t n>istream &operator>>(istream &is,array<T,n>&a){for(auto&i:a)is>>i;return is;}
template<typename T>istream &operator>>(istream &is,vector<T> &a){for(auto &i:a)is>>i;return is;}
template<typename T1,typename T2>void operator++(pair<T1,T2>&a,int n){a.first++,a.second++;}
template<typename T1,typename T2>void operator--(pair<T1,T2>&a,int n){a.first--,a.second--;}
template<typename T>void operator++(vector<T>&a,int n){for(auto &i:a)i++;}
template<typename T>void operator--(vector<T>&a,int n){for(auto &i:a)i--;}
#define overload3(_1,_2,_3,name,...) name
#define rep1(i,n) for(int i=0;i<(int)(n);i++)
#define rep2(i,l,r) for(int i=(int)(l);i<(int)(r);i++)
#define rep(...) overload3(__VA_ARGS__,rep2,rep1)(__VA_ARGS__)
#define reps(i,l,r) rep2(i,l,r)
#define all(x) x.begin(),x.end()
#define pcnt(x) __builtin_popcountll(x)
#define fin(x) return cout<<(x)<<'\n',static_cast<void>(0)
#define yn(x) cout<<((x)?"Yes\n":"No\n")
#define uniq(x) sort(all(x)),x.erase(unique(all(x)),x.end())
template<typename T>
inline int fkey(vector<T>&z,T key){return lower_bound(z.begin(),z.end(),key)-z.begin();}
ll myceil(ll a,ll b){return (a+b-1)/b;}
template<typename T,size_t n,size_t id=0>
auto vec(const int (&d)[n],const T &init=T()){
  if constexpr (id<n)return vector(d[id],vec<T,n,id+1>(d,init));
  else return init;
}
#ifdef LOCAL
#include<debug.h>
#define SWITCH(a,b) (a)
#else
#define debug(...) static_cast<void>(0)
#define debugg(...) static_cast<void>(0)
#define SWITCH(a,b) (b)
template<typename T1,typename T2>ostream &operator<<(ostream &os,const pair<T1,T2>&p){os<<p.first<<' '<<p.second;return os;}
#endif
struct Timer{
  clock_t start;
  Timer(){
    start=clock();
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout<<fixed<<setprecision(16);
  }
  inline double now(){return (double)(clock()-start)/1000;}
  #ifdef LOCAL
  ~Timer(){
    cerr<<"time:";
    cerr<<now();
    cerr<<"ms\n";
  }
  #endif
}timer;
void SOLVE();
int main(){
  int testcase=1;
  //cin>>testcase;
  for(int i=0;i<testcase;i++){
    SOLVE();
  }
}
#include<type_traits>
struct has_update_impl{
  template<typename T>
  static auto check(T&&x)->decltype(x.update(),std::true_type{});
  template<typename T>
  static auto check(...)->std::false_type;
};
template<typename T>
struct has_update:public decltype(has_update_impl::check<T>(std::declval<T>())){};
template<typename T>
inline constexpr bool has_update_v=has_update<T>::value;
struct has_push_impl{
  template<typename T>
  static auto check(T&&x)->decltype(x.push(),std::true_type{});
  template<typename T>
  static auto check(...)->std::false_type;
};
template<typename T>
struct has_push:public decltype(has_push_impl::check<T>(std::declval<T>())){};
template<typename T>
inline constexpr bool has_push_v=has_push<T>::value;
struct has_middle_impl{
  template<typename T>
  static auto check(T&&x)->decltype(x.middle,std::true_type{});
  template<typename T>
  static auto check(...)->std::false_type;
};
template<typename T>
struct has_middle:public decltype(has_middle_impl::check<T>(std::declval<T>())){};
template<typename T>
inline constexpr bool has_middle_v=has_middle<T>::value;

template<typename T,bool no_push=false>
void splay(T*nd){
  if constexpr(has_push_v<T>&&!no_push)nd->push();
  while(nd->par){
    T *p=nd->par;
    T *pp=p->par;
    if constexpr(has_push_v<T>&&!no_push){
      if(pp)pp->push();
      p->push();
      nd->push();
    }
    if(p->left==nd){
      if(pp){
        if(pp->left==p){
          nd->par=pp->par;
          if(pp->par){
            if constexpr(has_middle_v<T>){
              if(pp->par->middle==pp)nd->par->middle=nd;
              else if(pp->par->left==pp)nd->par->left=nd;
              else if(pp->par->right==pp)nd->par->right=nd;
            }
            else{
              if(pp->par->left==pp)nd->par->left=nd;
              else if(pp->par->right==pp)nd->par->right=nd;
            }
          }
          pp->left=p->right;
          if(pp->left)pp->left->par=pp;
          p->left=nd->right;
          if(p->left)p->left->par=p;
          nd->right=p;
          p->par=nd;
          p->right=pp;
          pp->par=p;
          if constexpr(has_update_v<T>)pp->update(),p->update(),nd->update();
          continue;
        }
        else if(pp->right==p){
          nd->par=pp->par;
          if(pp->par){
            if constexpr(has_middle_v<T>){
              if(pp->par->middle==pp)nd->par->middle=nd;
              else if(pp->par->left==pp)nd->par->left=nd;
              else if(pp->par->right==pp)nd->par->right=nd;
            }
            else{
              if(pp->par->left==pp)nd->par->left=nd;
              else if(pp->par->right==pp)nd->par->right=nd;
            }
          }
          p->left=nd->right;
          if(p->left)p->left->par=p;
          pp->right=nd->left;
          if(pp->right)pp->right->par=pp;
          nd->left=pp;
          pp->par=nd;
          nd->right=p;
          p->par=nd;
          if constexpr(has_update_v<T>)pp->update(),p->update(),nd->update();
          continue;
        }
      }
      nd->par=pp;
      if(pp){
        if constexpr(has_middle_v<T>){
          if(pp->middle==p)pp->middle=nd;
          else if(pp->left==p)pp->left=nd;
          else if(pp->right==p)pp->right=nd;
        }
        else{
          if(pp->left==p)pp->left=nd;
          else if(pp->right==p)pp->right=nd;
        }
      }
      p->left=nd->right;
      if(p->left)p->left->par=p;
      nd->right=p;
      p->par=nd;
      if constexpr(has_update_v<T>)p->update(),nd->update();
      break;
    }
    else if(p->right==nd){
      if(pp){
        if(pp->left==p){
          nd->par=pp->par;
          if(pp->par){
            if constexpr(has_middle_v<T>){
              if(pp->par->middle==pp)nd->par->middle=nd;
              else if(pp->par->left==pp)nd->par->left=nd;
              else if(pp->par->right==pp)nd->par->right=nd;
            }
            else{
              if(pp->par->left==pp)nd->par->left=nd;
              else if(pp->par->right==pp)nd->par->right=nd;
            }
          }
          p->right=nd->left;
          if(p->right)p->right->par=p;
          pp->left=nd->right;
          if(pp->left)pp->left->par=pp;
          nd->left=p;
          p->par=nd;
          nd->right=pp;
          pp->par=nd;
          if constexpr(has_update_v<T>)pp->update(),p->update(),nd->update();
          continue;
        }
        else if(pp->right==p){
          nd->par=pp->par;
          if(pp->par){
            if constexpr(has_middle_v<T>){
              if(pp->par->middle==pp)nd->par->middle=nd;
              else if(pp->par->left==pp)nd->par->left=nd;
              else if(pp->par->right==pp)nd->par->right=nd;
            }
            else{
              if(pp->par->left==pp)nd->par->left=nd;
              else if(pp->par->right==pp)nd->par->right=nd;
            }
          }
          pp->right=p->left;
          if(pp->right)pp->right->par=pp;
          p->right=nd->left;
          if(p->right)p->right->par=p;
          nd->left=p;
          p->par=nd;
          p->left=pp;
          pp->par=p;
          if constexpr(has_update_v<T>)pp->update(),p->update(),nd->update();
          continue;
        }
      }
      nd->par=pp;
      if(pp){
        if constexpr(has_middle_v<T>){
          if(pp->middle==p)pp->middle=nd;
          else if(pp->left==p)pp->left=nd;
          else if(pp->right==p)pp->right=nd;
        }
        else{
          if(pp->left==p)pp->left=nd;
          else if(pp->right==p)pp->right=nd;
        }
      }
      p->right=nd->left;
      if(p->right)p->right->par=p;
      nd->left=p;
      p->par=nd;
      if constexpr(has_update_v<T>)p->update(),nd->update();
      break;
    }
    else break;
  }
}
template<typename T>
[[nodiscard]]T* near(T *nd,decltype(T::key)k){
  while(true){
    if(k<nd->key){
      if constexpr(has_push_v<T>)nd->push();
      if(nd->left)nd=nd->left;
      else{
        splay<T,true>(nd);
        return nd;
      }
    }
    else if(nd->key<k){
      if constexpr(has_push_v<T>)nd->push();
      if(nd->right)nd=nd->right;
      else{
        splay<T,true>(nd);
        return nd;
      }
    }
    else{
      splay<T,true>(nd);
      return nd;
    }
  }
  return nullptr;
}
template<typename T>
[[nodiscard]]T* get_k(T *nd,decltype(T::sz)k){
  while(true){
    if constexpr(has_push_v<T>)nd->push();
    decltype(T::sz) lsz=nd->left?nd->left->sz:0;
    if(lsz==k)break;
    else if(k<lsz)nd=nd->left;
    else{
      nd=nd->right;
      k-=1+lsz;
    }
  }
  splay<T,true>(nd);
  return nd;
}
template<typename T>
[[nodiscard]]T* merge(T* l,T *r){
  if(!l)return r;
  if(!r)return l;
  while(r->left){
    if constexpr(has_push_v<T>)r->push();
    r=r->left;
  }
  if constexpr(has_push_v<T>)r->push();
  splay<T,true>(r);
  r->left=l;
  l->par=r;
  if constexpr(has_update_v<T>)r->update();
  return r;
}
template<typename T,bool correct_parent=true>
[[nodiscard]]T* left_most(T*nd){
  T nil;
  T *rnd=&nil;
  while(nd->left){
    if constexpr(has_push_v<T>)nd->push();
    T *c=nd->left;
    if(!c->left){
      rnd->left=nd;
      if constexpr(has_update_v<T>)nd->par=rnd;
      rnd=rnd->left;
      nd=c;
    }
    else{
      if constexpr(has_push_v<T>)c->push();
      nd->left=c->right;
      c->right=nd;
      if constexpr(has_update_v<T>&&correct_parent){
        if(nd->left)nd->left->par=nd;
        nd->par=c;
      }
      if constexpr(has_update_v<T>){
        nd->update();
        c->par=rnd;
      }
      rnd->left=c;
      nd=c->left;
      rnd=rnd->left;
    }
  }
  if constexpr(has_push_v<T>)nd->push();
  rnd->left=nd->right;
  nd->right=nil.left;
  nil.left=nil.right=nullptr;
  if constexpr(has_update_v<T>&&correct_parent){
    if(rnd->left)rnd->left->par=rnd;
    if(nd->right)nd->right->par=nd;
    nd->par=nullptr;
  }
  if constexpr(has_update_v<T>){
    while(rnd){
      rnd->update();
      rnd=rnd->par;
    }
  }
  return nd;
}
template<typename T,bool correct_parent=true>
[[nodiscard]]T* right_most(T*nd){
  T nil;
  T *lnd=&nil;
  while(nd->right){
    if constexpr(has_push_v<T>)nd->push();
    T *c=nd->right;
    if(!c->right){
      lnd->right=nd;
      if constexpr(has_update_v<T>)nd->par=lnd;
      lnd=lnd->right;
      nd=c;
    }
    else{
      if constexpr(has_push_v<T>)c->push();
      nd->right=c->left;
      c->left=nd;
      if constexpr(has_update_v<T>&&correct_parent){
        if(nd->right)nd->right->par=nd;
        nd->par=c;
      }
      if constexpr(has_update_v<T>){
        nd->update();
        c->par=lnd;
      }
      lnd->right=c;
      nd=c->right;
      lnd=lnd->right;
    }
  }
  if constexpr(has_push_v<T>)nd->push();
  lnd->right=nd->left;
  nd->left=nil.right;
  nil.left=nil.right=nullptr;
  if constexpr(has_update_v<T>&&correct_parent){
    if(lnd->right)lnd->right->par=lnd;
    if(nd->left)nd->left->par=nd;
    nd->par=nullptr;
  }
  if constexpr(has_update_v<T>){
    while(lnd){
      lnd->update();
      lnd=lnd->par;
    }
  }
  return nd;
}
template<typename T,T limit>
struct SlopeTrick{
private:
  static_assert(std::is_integral_v<T>);
  static_assert(limit>0);
  struct node{
    node *left,*right,*par;
    T pos,slope,len;
    T posr,slope_sum,len_sum;
    T lazy,p_add;
    node():left(nullptr),right(nullptr),par(nullptr),pos(0),slope(0),len(0),posr(0),slope_sum(0),len_sum(0),lazy(0),p_add(0){}
    void propagate(T f,T g){
      lazy+=f;
      p_add+=g;
      slope+=f;
      slope_sum+=f*len_sum;
      pos+=g;
      posr+=g;
    }
    void push(){
      if(left)left->propagate(lazy,p_add);
      if(right)right->propagate(lazy,p_add);
      lazy=0;
      p_add=0;
    }
    void update(){
      posr=pos;
      slope_sum=slope*len;
      len_sum=len;
      if(left){
        slope_sum+=left->slope_sum;
        len_sum+=left->len_sum;
      }
      if(right){
        posr=right->posr;
        slope_sum+=right->slope_sum;
        len_sum+=right->len_sum;
      }
    }
    ~node(){
      if(left)delete left;
      if(right)delete right;
    }
  };
  void search_slope(T slope){
    while(true){
      root->push();
      if(root->slope==slope)break;
      else if(root->slope>slope){
        if(root->left)root=root->left;
        else break;
      }
      else{
        if(root->right)root=root->right;
        else break;
      }
    }
    splay<node,true>(root);
  }
  std::pair<node*,node*>split(node *nd,T pos,T l=-limit){
    while(true){
      nd->push();
      T pl=l;
      if(nd->left)l=nd->left->posr;
      if(l<pos&&pos<=nd->pos){
        splay(nd);
        if(pos==nd->pos){
          node *rnd=nd->right;
          nd->right=nullptr;
          rnd->par=nullptr;
          nd->update();
          return std::make_pair(nd,rnd);
        }
        else{
          node *lnd=new node();
          lnd->slope=nd->slope;
          lnd->pos=pos;
          lnd->len=pos-l;
          lnd->left=nd->left;
          if(lnd->left)lnd->left->par=lnd;
          lnd->update();
          nd->left=nullptr;
          nd->len=nd->pos-pos;
          nd->update();
          return std::make_pair(lnd,nd);
        }
      }
      else if(pos<nd->pos)l=pl,nd=nd->left;
      else l=nd->pos,nd=nd->right;
    }
    __builtin_unreachable();
  }
  node *root;
  T lv;
public:
  SlopeTrick():root(new node()),lv(0){
    root->pos=root->posr=limit;
    root->len=root->len_sum=limit*2;
  }
  void add(T b){lv+=b;}
  void add_abs(T a,T c=1){
    lv+=c*(a-(-limit));
    root->propagate(-c,0);
    add_r(a,c*2);
  }
  void add_l(T a,T c=1){
    lv+=c*(a-(-limit));
    root->propagate(-c,0);
    add_r(a,c);
  }
  void add_r(T a,T c=1){
    node *nd=root;
    while(true){
      nd->push();
      if(a<nd->pos){
        if(nd->left&&a<nd->left->posr)nd=nd->left;
        else break;
      }
      else{
        if(nd->right)nd=nd->right;
        else break;
      }
    }
    splay<node,true>(nd);
    T l=nd->left?nd->left->posr:-limit;
    T r=nd->pos;
    if(l==a){
      node *l_tmp=nd->left;
      nd->left=nullptr;
      nd->propagate(c,0);
      nd->push();
      nd->left=l_tmp;
      nd->update();
      root=nd;
    }
    else{
      node *lnd=new node();
      lnd->left=nd->left;
      if(lnd->left)lnd->left->par=lnd;
      lnd->pos=a;
      lnd->len=a-l;
      lnd->slope=nd->slope;
      lnd->update();
      nd->left=nullptr;
      nd->len=r-a;
      nd->update();
      nd->propagate(c,0);
      nd->push();
      nd->left=lnd;
      lnd->par=nd;
      nd->update();
      root=nd;
    }
  }
  void add(SlopeTrick rhs){
    node *top=nullptr;
    T l=-limit;
    auto dfs=[&](auto self,node *nd)->void {
      if(!nd)return;
      nd->push();
      self(self,nd->left);
      if(top)top->push();
      if(nd->pos==limit){
        root->propagate(nd->slope,0);
        if(top)top->right=root;
        root->par=top;
      }
      else{
        auto [left,right]=split(root,nd->pos,l);
        left->propagate(nd->slope,0);
        if(top)top->right=left;
        left->par=top;
        top=left;
        root=right;
        l=top->posr;
      }
      self(self,nd->right);
    };
    dfs(dfs,rhs.root);
    while(root->par){
      root=root->par;
      root->update();
    }
    lv+=rhs.lv;
  }
  T convolution_l(T c){
    root=left_most(root);
    if(root->slope>=-c)return -limit;
    while(root->slope<-c){
      root->push();
      lv+=(c+root->slope)*root->len;
      node *nxt=root->right;
      if(!nxt){
        root->len=limit*2;
        root->slope=-c;
        root->update();
        return limit;
      }
      root->right=nullptr;
      nxt->par=nullptr;
      delete root;
      root=left_most(nxt);
    }
    if(root->slope==-c){
      T res=root->pos-root->len;
      root->len=root->pos-(-limit);
      root->update();
      return res;
    }
    node *nd=new node();
    nd->pos=root->pos-root->len;
    nd->len=nd->pos-(-limit);
    nd->slope=-c;
    nd->par=root;
    root->left=nd;
    nd->update();
    root->update();
    return nd->pos;
  }
  T convolution_r(T c){
    root=right_most(root);
    if(root->slope<=c)return limit;
    while(root->slope>c){
      root->push();
      node *nxt=root->left;
      if(!nxt){
        root->len=limit*2;
        root->pos=limit;
        root->slope=c;
        root->update();
        return -limit;
      }
      root->left=nullptr;
      nxt->par=nullptr;
      delete root;
      root=right_most(nxt);
    }
    if(root->slope==c){
      T res=root->pos;
      root->len+=limit-root->pos;
      root->pos=limit;
      root->update();
      return res;
    }
    node *nd=new node();
    nd->pos=limit;
    nd->len=limit-root->pos;
    nd->slope=c;
    nd->par=root;
    root->right=nd;
    nd->update();
    root->update();
    return root->pos;
  }
  std::pair<T,T>convolution_abs(T c){
    T l=convolution_l(c);
    T r=convolution_r(c);
    return std::make_pair(l,r);
  }
  void convolution(SlopeTrick&rhs){
    auto dfs=[&](auto self,node *nd)->void {
      if(!nd)return;
      nd->push();
      node *rnd=nd->right;
      self(self,nd->left);
      search_slope(nd->slope);
      if(nd->slope==root->slope){
        node *l_tmp=root->left;
        root->left=nullptr;
        root->len+=nd->len;
        root->propagate(0,nd->len);
        root->push();
        root->left=l_tmp;
        root->update();
        nd->left=nd->right=nullptr;
        delete nd;
      }
      else if(nd->slope<root->slope){
        node *l_tmp=root->left;
        root->left=nullptr;
        root->propagate(0,nd->len);
        root->push();
        root->left=nd;
        nd->par=root;
        nd->left=l_tmp;
        nd->right=nullptr;
        if(l_tmp)l_tmp->par=nd;
        nd->pos=(l_tmp?l_tmp->posr:-limit)+nd->len;
        nd->update();
        root->update();
      }
      else{
        node *r_tmp=root->right;
        root->right=nd;
        nd->par=root;
        nd->left=nullptr;
        nd->right=r_tmp;
        if(r_tmp)r_tmp->par=nd;
        if(nd->right)nd->right->propagate(0,nd->len);
        nd->pos=(root->left?root->left->posr:-limit)+root->len+nd->len;
        nd->update();
        root->update();
      }
      self(self,rnd);
    };
    lv+=rhs.lv;
    dfs(dfs,rhs.root);
    rhs.root=nullptr;
    auto [lnd,tmp]=split(root,0);
    auto [mnd,rnd]=split(tmp,limit*2);
    root=mnd;
    root->propagate(0,-limit);
    lv+=lnd->slope_sum;
    delete lnd;
    delete rnd;
  }
  T min(){
    search_slope(0);
    if(root->slope>=0){
      if(!root->left)return lv;
      return lv+root->left->slope_sum;
    }
    else{
      T res=lv;
      if(root->left)res+=root->left->slope_sum;
      res+=root->slope*root->len;
      return res;
    }
  }
  std::pair<T,T>amin(){
    search_slope(0);
    if(root->slope==0){
      T l=root->left?root->left->posr:-limit;
      return std::make_pair(l,root->pos);
    }
    else if(root->slope>0){
      T l=root->left?root->left->posr:-limit;
      return std::make_pair(l,l);
    }
    else{
      return std::make_pair(root->pos,root->pos);
    }
  }
  T get(T x){
    T res=lv;
    T l=-limit;
    while(true){
      root->push();
      T pl=l;
      if(root->left)l=root->left->posr;
      T r=root->pos;
      if(l<=x&&x<=r){
        if(root->left)res+=root->left->slope_sum;
        res+=root->slope*(x-l);
        break;
      }
      else if(x<l)root=root->left,l=pl;
      else{
        if(root->left)res+=root->left->slope_sum;
        res+=root->slope*root->len;
        l=root->pos;
        root=root->right;
      }
    }
    splay<node,true>(root);
    return res;
  }
  void destruct(){
    if(root)delete root;
    root=nullptr;
  }
  std::vector<T>slice(T l,T r){
    std::vector<T>res(r-l+1);
    for(T i=l;i<=r;i++)res[i-l]=this->get(i);
    return res;
  }
};
constexpr ll inf=1e9+1000;
void SOLVE(){
  int m,n;
  cin>>m>>n;
  vector<ll>a(m),b(n);
  cin>>a>>b;
  rep(k,1,m+1){
    vector<pair<int,int>>c;
    c.reserve(n+m);
    rep(i,m)c.emplace_back(a[i],-1);
    rep(i,n)c.emplace_back(b[i],k);
    sort(all(c));
    debug(c);
    SlopeTrick<ll,1<<20>dp;
    if(c[0].second==-1){
      dp.add_abs(-1,inf);
    }
    else{
      dp.add_r(c[0].second,inf);
      dp.add_l(0,inf);
    }
    rep(i,1,c.size()){
      if(c[i].first!=c[i-1].first){
        dp.add_abs(0,c[i].first-c[i-1].first);
      }
      SlopeTrick<ll,1<<20>d;
      if(c[i].second==-1){
        d.add_abs(-1,inf);
      }
      else{
        d.add_r(c[i].second,inf);
        d.add_l(0,inf);
      }
      dp.convolution(d);
      debug(dp.slice(-3,3));
    }
    cout<<dp.get(0)<<'\n';
    dp.destruct();
  }
}
0