Submission #1200234

#TimeUsernameProblemLanguageResultExecution timeMemory
1200234justinlgl20Train (APIO24_train)C++20
40 / 100
371 ms85364 KiB
#include <bits/stdc++.h> #include "train.h" using namespace std; #define int long long #define all(x) (x).begin(), (x).end() template<template<typename> class Container, typename G> ostream& operator<<(ostream& os, Container<G> x) { int f = 0; os << '{'; for (auto &i: x) os << (f++ ? ", " : ""), os << i; os << "}"; return os; } void _print() {cerr << "]\n";} template<typename T, typename... V> void _print(T t, V... v) {cerr << t; if (sizeof...(v)) cerr <<", "; _print(v...);} #ifdef DEBUG #define dbg(x...) cerr << "\e[91m"<<__func__<<":"<<__LINE__<<" [" << #x << "] = ["; _print(x); cerr << "\e[39m" << endl; #else #define dbg(x...) #endif #define pii pair<int, int> #define f first #define s second const int INF=1e18; struct path{ int a,b,u,v,c,inx;//u->v path(){inx=0;}; bool operator<(path other){ return b>other.b; } }; struct wavelet{ int tl,tr;wavelet *l,*r;vector<int> b; wavelet(){} wavelet(int *from,int *to,int x,int y){ tl=x,tr=y; if(tl==tr or from>=to)return; int tm=(tl+tr)>>1; auto f=[tm](int x){return x<=tm;}; b.reserve(to-from+1); b.push_back(0); for(auto it=from;it!=to;it++){ b.push_back(b.back()+f(*it)); } auto pivot=stable_partition(from,to,f); l=new wavelet(from,pivot,tl,tm); r=new wavelet(pivot,to,tm+1,tr); } int LTE(int l,int r,int k){ if(l>r or k<tl)return 0; if(tr<=k)return r-l+1; int lb=b[l-1],rb=b[r]; return this->l->LTE(lb+1ll,rb,k)+this->r->LTE(l-lb,r-rb,k); } ~wavelet(){ delete l;delete r; } }; // need range inside queries in log, so we use pseg or merge sort tree template<int sz> struct interval{ vector<pii> v; wavelet *t; int a[sz]; void init(){ v.clear(); delete t; } void add(int l,int r){ v.emplace_back(l,r); } void process(){ sort(all(v)); for(int i=0;i<v.size();i++)a[i]=v[i].s; t=new wavelet(a,a+v.size(),0,sz); } int query(int l,int r){ int inx=lower_bound(all(v),make_pair(l,0ll))-v.begin();int inx2=upper_bound(all(v),make_pair(r,INF))-v.begin()-1; int ans=t->LTE(inx+1,inx2+1,r); //int ans=0;for(int i=inx;i<=inx2;i++)ans+=(v[i].s<=r); return ans; } }; interval<1<<20> ds; template<typename T> struct lct { // queries are increasing int tl,tr;lct<T> *l,*r; T f; lct(){ init(); } lct(int a,int b){ init(a,b); } // changing r changes the answer wtf void init(int l=0,int r=1<<20){ // increasing r makes it bigger tl=l;tr=r;this->l=NULL;this->r=NULL;f={INF,0ll,INF}; } void add(T l){ int tm=(tl+tr)>>1; if(make_pair(f.get(tm),f.b)>make_pair(l.get(tm),l.b))swap(l,f); if(f.get(tl)<=l.get(tl) and f.get(tr)<=l.get(tr))return; if(tl==tr)return; if(f.get(tl)>l.get(tl)){ if(!this->l)this->l=new lct(tl,tm); this->l->add(f); }else{// if(f.get(tr)>l.get(tr)){ if(!r)r=new lct(tm+1ll,tr); r->add(f); } } int query(int x){ int tm=(tl+tr)>>1; int ans=f.get(x); if(tl==tr)return ans; if(x<=tm and l){ ans=min(ans,l->query(x)); }else if(r){ ans=min(ans,r->query(x)); } return ans; } }; /* template<typename T> struct lct { // queries are increasing vector<T> v; void init(){ v.clear(); } void add(T l){ v.push_back(l); } int query(int x){ int ans=1e18; for(auto i:v)ans=min(ans,i.get(x)); return ans; } };*/ struct F{ int c,m,b; int get(int x){ //if(c>=INF)return c; //if(x<=b)return c; return c+m*(ds.query(b+1ll,x)); } const bool operator<(F other)const { return b>other.b; } }; priority_queue<F> ins[100005]; lct<F> cht[100005]; int solve(int32_t n,int32_t m,int32_t w,vector<int32_t>t,vector<int32_t>_x,vector<int32_t>_y,vector<int32_t>_a,vector<int32_t>_b,vector<int32_t>_c,vector<int32_t>l,vector<int32_t>r){ for(int i=0;i<n;i++){ while(ins[i].size())ins[i].pop(); cht[i].init(); } ds.init(); vector<path> paths(m); vector<int> cmp={-1}; for(int i=0;i<m;i++){ paths[i].u=_x[i];paths[i].v=_y[i];paths[i].a=_a[i];paths[i].b=_b[i];paths[i].c=_c[i]; cmp.push_back(_a[i]);cmp.push_back(_b[i]); } for(int i=0;i<w;i++){ cmp.push_back(l[i]);cmp.push_back(r[i]); } sort(all(cmp));cmp.resize(unique(all(cmp))-cmp.begin()); for(int i=0;i<m;i++){ paths[i].a=lower_bound(all(cmp),paths[i].a)-cmp.begin(); paths[i].b=lower_bound(all(cmp),paths[i].b)-cmp.begin(); } for(int i=0;i<w;i++){ l[i]=lower_bound(all(cmp),l[i])-cmp.begin(); r[i]=lower_bound(all(cmp),r[i])-cmp.begin(); ds.add(l[i],r[i]); } ds.process(); sort(all(paths),[&](path a,path b){ return a.a<b.a; }); for(int i=0;i<m;i++)paths[i].inx=i; // need to put a queue of paths just processed to insert ordered by b value cht[0].add(F{0,t[0],-1}); for(path i:paths){ // 1. update i.u until we get to i.a while(ins[i.u].size() and ins[i.u].top().b<=i.a){ cht[i.u].add(ins[i.u].top());ins[i.u].pop(); } // 2. query cht[i.u] for our i.a-1 value int v=cht[i.u].query(i.a-1ll)+i.c; v=min(INF,v); dbg(i.u,i.v,i.a,i.b,v); F ne;ne.c=v;ne.m=t[i.v];ne.b=i.b; // 3. insert the func that we make into ins[i.v].push(ne); } while(ins[n-1].size()){ cht[n-1].add(ins[n-1].top());ins[n-1].pop(); } int ans=cht[n-1].query(1<<20); if(ans>=INF)ans=-1; return ans; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...