Submission #944622

#TimeUsernameProblemLanguageResultExecution timeMemory
944622salmonMeetings (IOI18_meetings)C++14
0 / 100
272 ms32376 KiB
#include <bits/stdc++.h> #include "meetings.h" using namespace std; int N; int Q; int lst[250100]; long long int num[200100][25]; pair<int,int> st[500100]; pair<int,int> st1[500100]; void build(int i, int s, int e){ if(s == e){ st[i] = {lst[s],s}; st1[i] = {lst[s],-s}; return; } int m = (s + e)/2; build(i * 2,s,m); build(i * 2 + 1, m + 1, e); st[i] = max(st[i * 2],st[i * 2 + 1]); st1[i] = max(st1[i * 2],st1[i * 2 + 1]); } pair<int,int> query(int i, int s, int e, int S, int E){ if(S <= s && e <= E){ return st[i]; } int m = (s + e)/2; if(S <= m && m < E){ return max(query(i*2,s,m,S,E), query(i*2+1,m+1,e,S,E)); } if(S <= m) return query(i * 2, s, m ,S, E); if(m < E) return query(i * 2 + 1, m + 1, e, S, E); } pair<int,int> query1(int i, int s, int e, int S, int E){ if(S <= s && e <= E){ return st1[i]; } int m = (s + e)/2; if(S <= m && m < E){ return max(query1(i*2,s,m,S,E), query1(i*2+1,m+1,e,S,E)); } if(S <= m) return query1(i * 2, s, m ,S, E); if(m < E) return query1(i * 2 + 1, m + 1, e, S, E); } long long int recurse(int j, int l ,int r){ if(l > r) return 0; if(l == r) return j; long long int small = 1e18; vector<int> temp = {l - 1}; for(int i = l; i <= r; i++){ if(lst[i] == j) temp.push_back(i); } temp.push_back(r + 1); for(int i = 0; i < temp.size() - 1; i++){ long long int vum = recurse(j - 1,temp[i] + 1, temp[i + 1] - 1) + (temp[i] - l + 1 + r - temp[i + 1] + 1) * j; small = min(small, vum); num[temp[i + 1] - 1][j] = vum - (r - l + 1) * j; } return small; } struct node{ int s, e, m; node *l, *r; long long int v; int j; node(int S, int E, int J){ s = S; e = E; m = (s + e)/2; j = J; if(s == e){ v = num[s][j]; } else{ l = new node(s,m,J); r = new node(m + 1, e,J); v = min(l -> v, r -> v); } } long long int query(int S, int E){ if(S <= s && e <= E) return v; long long int V = 1e18; if(S <= m){ V = min(V , l -> query(S,E)); } if(m < E){ V = min(V, r -> query(S,E)); } return V; } } *nodes[25]; vector<long long> minimum_costs(vector<int> H, vector<int> L, vector<int> R) { N = H.size(); Q = L.size(); for(int i = 1; i <= N; i++){ lst[i] = H[i - 1]; } for(int i = 0; i <= N; i++){ for(int j = 0; j <= 20; j++){ num[i][j] = 1e18; } } recurse(20,1,N); for(int j = 0; j <= 20; j++){ nodes[j] = new node(1,N,j); } build(1,1,N); vector<long long int> banna; for(int i = 0; i < Q; i++){ vector<vector<long long int>> v1; v1.push_back({0,L[i]+1,R[i]+1,0}); long long int ans = 1e18; long long int cont = 20; while(cont >= 0){ vector<vector<long long int>> temp; while(!v1.empty()){ vector<long long int> v = v1.back(); v1.pop_back(); long long int k = ans; pair<int,int> p = query(1,1,N,v[1],v[2]); if(p.first != cont){ temp.push_back(v); continue; } if(v[2] == v[1]){ // printf("\nba h %lld\n",cont); ans = min(ans, cont + v[0]); continue; } pair<int,int> p1 = query1(1,1,N,v[1],v[2]); if(v[3] == 0){ if(p.second == -p1.second){ int it = p.second; if(it != v[1]){ temp.push_back({v[0] + cont * (v[2] - it + 1), v[1], it - 1,2}); } if(it != v[2]){ temp.push_back({v[0] + cont * (it - v[1] + 1), it + 1, v[2],1}); } } else{ int it = p.second; int it1 = -p.second; if(it != v[1]){ temp.push_back({v[0] + cont * (v[2] - it + 1), v[1], it - 1, 2}); } if(it1 != v[2]){ temp.push_back({v[0] + cont * (it1 - v[1] + 1), it1 + 1, v[2],1}); } ans = min(ans, cont * (v[2] - v[1] + 1) + nodes[cont] -> query(it + 1, it1)); } } else if(v[3] == 1){ if(p.second == -p1.second){ int it = p.second; if(it != v[1]){ ans = min(ans, cont * (v[2] - v[1] + 1) + nodes[cont] -> query(v[2],v[2])); } if(it != v[2]){ temp.push_back({v[0] + cont * (it - v[1] + 1), it + 1, v[2],1}); } } else{ int it = p.second; int it1 = -p.second; if(it != v[1]){ ans = min(ans, cont * (v[2] - v[1] + 1) + nodes[cont] -> query(v[2],v[2])); } if(it1 != v[2]){ temp.push_back({v[0] + cont * (it1 - v[1] + 1), it1 + 1, v[2],1}); } ans = min(ans, cont * (v[2] - v[1] + 1) + nodes[cont] -> query(it + 1, it1)); } } else{ if(p.second == -p1.second){ int it = p.second; if(it != v[1]){ temp.push_back({v[0] + cont * (v[2] - it + 1), v[1], it - 1,2}); } if(it != v[2]){ ans = min(ans, cont * (v[2] - v[1] + 1) + nodes[cont] -> query(v[2], v[2])); } } else{ int it = p.second; int it1 = -p.second; if(it != v[1]){ temp.push_back({v[0] + cont * (v[2] - it + 1), v[1], it - 1, 2}); } if(it1 != v[2]){ ans = min(ans, cont * (v[2] - v[1] + 1) + nodes[cont] -> query(v[2], v[2])); } ans = min(ans, cont * (v[2] - v[1] + 1) + nodes[cont] -> query(it + 1, it1)); } } ans = min(ans + v[0],k); } v1 = temp; cont--; } banna.push_back(ans); } return banna; }

Compilation message (stderr)

meetings.cpp: In function 'long long int recurse(int, int, int)':
meetings.cpp:74:22: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   74 |     for(int i = 0; i < temp.size() - 1; i++){
      |                    ~~^~~~~~~~~~~~~~~~~
meetings.cpp: In function 'std::pair<int, int> query(int, int, int, int, int)':
meetings.cpp:42:1: warning: control reaches end of non-void function [-Wreturn-type]
   42 | }
      | ^
meetings.cpp: In function 'std::pair<int, int> query1(int, int, int, int, int)':
meetings.cpp:57:1: warning: control reaches end of non-void function [-Wreturn-type]
   57 | }
      | ^
#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...