Submission #826430

#TimeUsernameProblemLanguageResultExecution timeMemory
826430MohamedAhmed04Long Distance Coach (JOI17_coach)C++14
16 / 100
4 ms596 KiB
#pragma GCC optimize("trapv") #include <bits/stdc++.h> using namespace std ; struct Point { long long x , y ; }; bool Is_Overflow(long long a , long long b) { if(a > 0 && (long long)(4e18) / a < b) return true ; else return false ; } long long f(Point a , long long x) { if(Is_Overflow(x , a.x)) return (3e18 + 100) ; else return (x * a.x + a.y) ; } const long long inf = 3e18 ; const int MAX = 2e5 + 10 ; const int MAX2 = 1e7 + 10 ; long long arr[MAX] ; int n , m ; long long x , t , w ; vector< pair<long long , long long> >vp ; long long val[MAX] , pref[MAX] ; long long dp[MAX] ; int L[MAX2] , R[MAX2] ; Point Line[MAX2] ; int id = 1 ; void init() { for(int i = 1 ; i < MAX2 ; ++i) Line[i].x = 0 , Line[i].y = inf ; } int Left(int node) { if(!L[node]) L[node] = ++id ; return L[node] ; } int Right(int node) { if(!R[node]) R[node] = ++id ; return R[node] ; } void Add_Line(Point p , int node = 1 , long long l = 0 , long long r = 1e12 + 100) { long long m = l + (r-l) / 2ll ; bool lef = f(p , l) < f(Line[node] , l) ; bool mid = f(p , m) < f(Line[node] , m) ; if(mid) swap(Line[node] , p) ; if(r-l == 1) return ; if(lef != mid) Add_Line(p , Left(node) , l , m) ; else Add_Line(p , Right(node) , m , r) ; } long long query(long long x , int node = 1 , long long l = 0 , long long r = 1e12 + 100) { long long m = l + (r-l) / 2ll ; long long now = f(Line[node] , x) ; if(r-l == 1) return now ; else if(x < m) return min(now , query(x , Left(node) , l , m)) ; else return min(now , query(x , Right(node) , m , r)) ; } int main() { ios_base::sync_with_stdio(0) ; cin.tie(0) ; cin>>x>>n>>m>>w>>t ; for(int i = 1 ; i <= n ; ++i) cin>>arr[i] ; for(int i = 1 ; i <= m ; ++i) { long long a , b ; cin>>a>>b ; vp.emplace_back(a , b) ; } vp.emplace_back(0 , 0) ; sort(arr+1 , arr+n+1) ; sort(vp.begin() , vp.end()) ; for(int i = 1 ; i <= m ; ++i) val[i] = inf , pref[i] = pref[i-1] + vp[i].second ; arr[n+1] = x ; for(int i = 1 ; i <= n+1 ; ++i) { int l = 1 , r = m ; int idx = -1 ; while(l <= r) { int mid = (l + r) >> 1 ; if(arr[i] % t >= vp[mid].first) idx = mid , l = mid+1 ; else r = mid-1 ; } if(idx != -1) val[idx] = min(val[idx] , arr[i] / t) ; } Point p ; p.x = 0 , p.y = 0 ; Add_Line(p) ; for(int i = 1 ; i <= m ; ++i) { dp[i] = dp[i-1] + x/t * w ; if(x%t > vp[i].first) dp[i] += w ; if(val[i] != inf) { //dp[j] + pref[i] - pref[j] + (i-j) * val[i] * w dp[i] = min(dp[i] , pref[i] + i * val[i] * w + query(val[i])) ; //for(int j = i-1 ; j >= 0 ; --j) // dp[i] = min(dp[i] , dp[j] + pref[i] - pref[j] + (i-j) * val[i] * w) ; } p.x = -i * w , p.y = dp[i] - pref[i] ; Add_Line(p) ; } dp[m] += (x / t + 1) * w ; return cout<<dp[m]<<"\n" , 0 ; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...