제출 #1154389

#제출 시각아이디문제언어결과실행 시간메모리
1154389Chris_BlackLong Distance Coach (JOI17_coach)C++20
큐에 대기중
0 ms0 KiB
#include <bits/stdc++.h> #include <ext/pb_ds/assoc_container.hpp> using namespace __gnu_pbds; using namespace std; typedef tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update> indexed_set; template <typename T> using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>; template<typename T> using ordered_multiset = tree<T, null_type, less_equal<T>, rb_tree_tag, tree_order_statistics_node_update>; struct custom_hash { static uint64_t splitmix64(uint64_t x) { // http://xorshift.di.unimi.it/splitmix64.c x += 0x9e3779b97f4a7c15; x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9; x = (x ^ (x >> 27)) * 0x94d049bb133111eb; return x ^ (x >> 31); } size_t operator()(uint64_t x) const { static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count(); return splitmix64(x + FIXED_RANDOM); } }; struct custom_hash_pair { static uint64_t splitmix64(uint64_t x) { x += 0x9e3779b97f4a7c15; x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9; x = (x ^ (x >> 27)) * 0x94d049bb133111eb; return x ^ (x >> 31); } size_t operator()(pair<uint64_t,uint64_t> x) const { static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count(); return splitmix64(x.first + FIXED_RANDOM)^(splitmix64(x.second + FIXED_RANDOM) >> 1); } }; mt19937 rnd(); #define all(x) (x).begin(), (x).end() #define allg(x) (x).begin(), (x).end(), greater<int>() using ull = unsigned long long; using ll = long long; using ld = double; using vi = vector<int>; using vb = vector<bool>; using vl = vector<ll>; using vd = vector<ld>; using si = set<int>; using ssi = set<si>; using sl = set<ll>; using ssl = set<sl>; using vvi = vector<vi>; using vvl = vector<vl>; using pii = pair<int,int>; using pll = pair<ll,ll>; using vs = vector<string>; using vpi = vector<pii>; using vvpi = vector<vpi>; using vpl = vector<pll>; using vvpl = vector<vpl>; #define FOR(i, a, b) for(int i = a; i <= b; ++i) #define FORR(i, a, b) for(int i = a; i >= b; --i) #define umap unordered_map #define eb emplace_back #define pb push_back #define lb lower_bound #define ub upper_bound #define mp make_pair #define ff first #define ss second #define ar array inline void yn(bool b) { if(b==true) cout<<"Yes\n"; else cout<<"No\n"; } inline void fastio() { ios_base::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); } template <int MOD=998'244'353> struct Modular { int value; static const int MOD_value = MOD; Modular(long long v = 0) { value = v % MOD; if (value < 0) value += MOD;} Modular(long long a, long long b) : value(0){ *this += a; *this /= b;} Modular& operator+=(Modular const& b) {value += b.value; if (value >= MOD) value -= MOD; return *this;} Modular& operator-=(Modular const& b) {value -= b.value; if (value < 0) value += MOD;return *this;} Modular& operator*=(Modular const& b) {value = (long long)value * b.value % MOD;return *this;} friend Modular mexp(Modular a, long long e) { Modular res = 1; while (e) { if (e&1) res *= a; a *= a; e >>= 1; } return res; } friend Modular inverse(Modular a) { return mexp(a, MOD - 2); } Modular& operator/=(Modular const& b) { return *this *= inverse(b); } friend Modular operator+(Modular a, Modular const b) { return a += b; } friend Modular operator-(Modular a, Modular const b) { return a -= b; } friend Modular operator-(Modular const a) { return 0 - a; } friend Modular operator*(Modular a, Modular const b) { return a *= b; } friend Modular operator/(Modular a, Modular const b) { return a /= b; } friend std::ostream& operator<<(std::ostream& os, Modular const& a) {return os << a.value;} friend bool operator==(Modular const& a, Modular const& b) {return a.value == b.value;} friend bool operator!=(Modular const& a, Modular const& b) {return a.value != b.value;} }; template <typename T> struct Fenwick { vector<T> a; int n; Fenwick(): a(),n(0) {} Fenwick(int _n){ n = _n; a = vector<T>(n, T()); } void clear(){ a = vector<T>(n,T()); } void add(int p, T x){ for(;p < n ; p |= p+1) a[p] += x; } T get(int p){ if(p < 0 ) return T(); p = min(p,n-1); T res = T(); for(;p >= 0 ; p = (p & (p+1)) - 1) res += a[p]; return res; } T getSum(int l,int r){ return get(r-1) - get(l-1); } }; template<typename T, int Mod = 1e9 + 7> struct SegmentProd{ vector<T> adi; int n; SegmentProd(): adi(), n(0) {} SegmentProd(int _n){ n=_n; adi = vector<T>(4*n, (T)1); } void clear(){ adi = vector<T>(4*n,(T)1); } void update(int poz,ll val){ updateintern(1,1,n,poz,val); } ll query(int st,int dr){ return (queryintern(1,1,n,st,dr) % Mod); } ll queryintern(int nod,int st,int dr,int ST,int DR) { if(st>=ST && dr<=DR) return adi[nod] % Mod; int mij = (st+dr)/2; ll a=1,b=1; if(mij >= ST) a = queryintern(2*nod,st,mij,ST,DR); if(mij<DR) b = queryintern(2*nod+1,mij+1,dr,ST,DR); return (a*b)%Mod; } void updateintern(int nod,int st,int dr,int poz,ll val) { if(st==dr) {adi[nod] = val; return;} ll mij = (st+dr)/2; if(poz <= mij) updateintern(2*nod,st,mij,poz,val); else updateintern(2*nod+1,mij+1,dr,poz,val); if(st!=dr) adi[nod] = (adi[2*nod] * adi[2*nod+1]) % Mod; } }; template <typename T, int Mod = 1e9 + 7> struct SegmentSum{ vector<T> adi; int n; SegmentSum(): adi(), n(0) {} SegmentSum(int _n){ n = _n; adi = vector<T>(4*n,(T)0); } void clear(){ adi = vector<T>(4*n,0); } void update(int poz,int val){ updateintern(1,1,n,poz,val); } void updateintern(int nod,int st,int dr,int poz,int val) { if(st==dr){ adi[nod] = val; return; } int mij = (st+dr)/2; if(poz<=mij) updateintern(2*nod,st,mij,poz,val); else updateintern(2*nod+1,mij+1,dr,poz,val); if(st!=dr) adi[nod] = (adi[2*nod] + adi[2*nod+1]) % Mod; } ll query(int st,int dr){ return queryintern(1,1,n,st,dr); } ll queryintern(int nod,int st,int dr,int ST,int DR){ if(st>=ST && dr<=DR) return adi[nod]; ll a = 0, b = 0; ll mij = (st+dr)/2; if(mij >= ST) a = queryintern(2*nod,st,mij,ST,DR); if(mij < DR) b = queryintern(2*nod+1,mij+1,dr,ST,DR); return a+b; } }; //#define int long long const string TASK("cbarn"); ifstream fin(TASK + ".in"); ofstream fout(TASK + ".out"); //#define cin fin //#define cout fout int di[]={0,0,-1,1},dj[]={-1,1,0,0}; int d8i[]={-1,-1,-1,0,0,1,1,1},d8j[]={-1,0,1,-1,1,-1,0,1}; //const int Inf = 0x3f3f3f3f; const ll Inf = LLONG_MAX / 2; bool testCase = false; const ll N = 1e6 + 9, K = 9, LG = 27, Mod = 998244353; ll x, n, m, w, t, s[N], d[N], c[N], p[N], dp[N], sc[N]; vl opt[N]; pll operator - (pll const& a, pll const& b) { return {a.ff - b.ff, a.ss - b.ss}; } ll dot(pll const& a, pll const& b) { return a.ff * b.ff + a.ss * b.ss; } ll cross(pll const& a, pll const& b) { return a.ff * b.ss - a.ss * b.ff; } void solve_testcase() { cin >> x >> n >> m >> w >> t; FOR(i, 1, n)cin >> s[i]; ///LAST SPOT s[++ n] = x; FOR(i, 1, m)cin >> d[i] >> c[i]; ///DRIVER d[++ m] = 0, c[m] = Inf; FOR(i, 1, m)p[i] = i; sort(p + 1, p + m + 1, [](int x, int y){return d[x] < d[y];}); vl psj; FOR(i, 1, m)psj.pb(d[i]); sort(psj.begin(), psj.end()); FOR(i, 1, n) { auto e = upper_bound(psj.begin(), psj.end(), s[i] % t) - psj.begin(); if(e == 1)continue; opt[e].pb(s[i]); } dp[1] = (x / t + 1) * w; deque<pll> dq; FOR(i, 2, m) { dp[i] = dp[i - 1] + ((x - d[p[i]]) / t + 1) * w; sc[i] = sc[i - 1] + c[p[i]]; pll nw(i, sc[i - 1] - dp[i - 1]); while(dq.size() > 1 && cross(dq[dq.size() - 1] - dq[dq.size() - 2], nw - dq[dq.size() - 2]) >= 0) dq.pop_back(); dq.pb(nw); for(auto e : opt[i]) { ll c = (e / t) * w; int st = 0, dr = dq.size() - 1, m; ll cand = -Inf; while(st <= dr) { m = (st + dr) / 2; ll p1 = dot({c, 1}, dq[m]); ll p2 = -Inf; if(m + 1 < dq.size())p2 = dot({c, 1}, dq[m + 1]); cand = max(cand, max(p1, p2)); if(p1 <= p2)st = m + 1; else dr = m - 1; } dp[i] = min(dp[i], sc[i] + (i + 1) * c - cand); } } cout << dp[m] << '\n'; } /// Check for interruption of input!! signed main() { fastio(); int t=1; if (testCase) cin >> t; while (t--) solve_testcase(); return 0; }