Submission #1267116

#TimeUsernameProblemLanguageResultExecution timeMemory
1267116dima2101Railway Trip 2 (JOI22_ho_t4)C++20
87 / 100
1107 ms39704 KiB
#pragma GCC optimize("O3") #include <bits/stdc++.h> const int LOGN = 20; const int MAXN = 2e5 + 1; int up_max[MAXN][LOGN]; int up_min[MAXN][LOGN]; struct SegTree{ int n; std::vector<std::pair<int,int>> t; SegTree(int n):n(n){ t.resize(4 * n,{-1,-1}); } void upd(int i,int l,int r,int pos,int pos1,int x){ if(l == r - 1){ if(x > t[i].first){ t[i].first = x; t[i].second = pos1; } return; } int mid = (l + r) / 2; if(pos >= mid){ upd(2 * i + 2,mid,r,pos,pos1,x); }else{ upd(2 * i + 1,l,mid,pos,pos1,x); } t[i] = std::max(t[2 * i + 1],t[2 * i + 2]); } std::pair<int,int> query(int i,int l,int r,int ql,int qr){ if(l>=ql && r <= qr){ return t[i]; } if(l >= qr || ql >=r){ return {-1,-1}; } int mid = (l + r) / 2; return std::max(query(2 * i + 1,l,mid,ql,qr), query(2 *i + 2,mid,r,ql,qr)); } }; struct SegTree1{ int n; std::vector<std::pair<int,int>> t; SegTree1(int n):n(n){ t.resize(4 * n,{1e8,1e8}); } void upd(int i,int l,int r,int pos,int pos1,int x){ if(l == r - 1){ if(x < t[i].first){ t[i].first = x; t[i].second = pos1; } return; } int mid = (l + r) / 2; if(pos >= mid){ upd(2 * i + 2,mid,r,pos,pos1,x); }else{ upd(2 * i + 1,l,mid,pos,pos1,x); } t[i] = std::min(t[2 * i + 1],t[2 * i + 2]); } std::pair<int,int> query(int i,int l,int r,int ql,int qr){ if(l>=ql && r <= qr){ return t[i]; } if(l >= qr || ql >=r){ return {1e8,1e8}; } int mid = (l + r) / 2; return std::min(query(2 * i + 1,l,mid,ql,qr), query(2 *i + 2,mid,r,ql,qr)); } }; signed main(){ int n,k,m; std::cin>>n>>k>>m; SegTree t(n); SegTree1 t1(n); std::vector<std::pair<int,int>> all(m); for(int i =0 ;i < m;i++){ std::cin>>all[i].first>>all[i].second; all[i].first--; all[i].second--; if(all[i].first < all[i].second){ t.upd(0,0,n,all[i].first,i,all[i].second); }else{ t1.upd(0,0,n,all[i].first,i,all[i].second); } } int q; std::cin>>q; if(q * std::max(n,m) <= 1e7){ for(int i =0 ;i < m;i++){ if(all[i].first > all[i].second)std::swap(all[i].first,all[i].second); } for(int i = 0;i < q;i++){ int start,stop; std::cin>>start>>stop; start--; stop--; std::vector<int> dist(n,1e8); dist[start] = 0; std::queue<int> q; q.push(start); std::set<int> not_used; for(int i =0 ;i < n;i++){ not_used.insert(i); } not_used.erase(start); while(q.size() > 0){ int v = q.front(); // std::cout<<v<<std::endl; q.pop(); int left = std::max(0,v - k + 1); int right = v; auto r = t.query(0,0,n,left,right + 1); if(r.second != -1){ // std::cout<<"right"<<' '<<std::max(all[r.second].first,v)<<' '<<all[r.second].second<<std::endl; auto it = not_used.lower_bound(std::max(all[r.second].first,v)); std::vector<int> need_del; while(it != not_used.end() && *it <= all[r.second].second){ if(dist[*it] > dist[v] + 1){ dist[*it] = dist[v] + 1; q.push(*it); } need_del.push_back(*it); it++; } for(int i:need_del){ not_used.erase(i); } } left = v; right = std::min(n - 1,v + k - 1); // std::cout<<left<<' '<<right<<std::endl; auto l = t1.query(0,0,n,left,right + 1); if(l.second != 1e8){ // std::cout<<"left "<<all[l.second].first<<' '<<all[l.second].second<<std::endl; auto it = not_used.lower_bound(all[l.second].first); std::vector<int> need_del; while(it != not_used.end() && *it <= std::min(v,all[l.second].second)){ if(dist[*it] > dist[v] + 1){ dist[*it] = dist[v] + 1; q.push(*it); } need_del.push_back(*it); it++; } for(int i:need_del){ not_used.erase(i); } } } if(dist[stop] == 1e8){ std::cout<<-1<<std::endl; continue; } std::cout<<dist[stop]<<std::endl; } return 0; } for(int i = 0;i < m;i++){ if(all[i].first < all[i].second){ auto now = t.query(0,0,n,all[i].first,all[i].second +1); if(now.first > all[i].second){ up_max[i][0] = now.second; }else{ up_max[i][0] = i; } }else{ std::swap(all[i].second,all[i].first); auto now = t1.query(0,0,n,all[i].first,all[i].second + 1); if(now.first < all[i].first){ up_min[i][0] = now.second; }else{ up_min[i][0] = i; } } // std::cout<<i<<' '<<now.second<<std::endl; } for(int j =1;j < LOGN;j++){ for(int i = 0;i < m;i++){ up_max[i][j] = up_max[up_max[i][j - 1]][j - 1]; up_min[i][j] = up_min[up_min[i][j - 1]][j - 1]; } } while(q--){ int start,stop; std::cin>>start>>stop; start--; stop--; if(start < stop){ int left = std::max(0,start - k + 1); int right = start; auto now = t.query(0,0,n,left,right + 1); int tmp = now.second; if(now.second == -1){ std::cout<<-1<<std::endl; continue; } if(stop <= now.first){ std::cout<<1<<std::endl; continue; } // std::cout<<left<<' '<<right<<"dwhsf; "<<now.second<<std::endl; int ans = 1; for(int j = LOGN - 1;j>=0;j--){ // std::cout<<up_max[tmp][j]<<std::endl; if(all[up_max[tmp][j]].second < stop){ ans += (1<<j); tmp = up_max[tmp][j]; } } if(all[up_max[tmp][0]].second < stop){ std::cout<<-1<<std::endl; continue; } std::cout<<ans + 1<<std::endl; }else{ int left = start; int right = std::min(n - 1,start + k - 1); auto now = t1.query(0,0,n,left,right + 1); int tmp = now.second; // std::cout<<now.second<<' '<<now.first<<' '<<stop<<std::endl; if(now.second >= m){ std::cout<<-1<<std::endl; continue; } if(stop >= now.first){ std::cout<<1<<std::endl; continue; } // std::cout<<left<<' '<<right<<"dwhsf; "<<now.second<<std::endl; assert(tmp < m); int ans = 1; for(int j = LOGN - 1;j>=0;j--){ // std::cout<<up_max[tmp][j]<<std::endl; if(all[up_min[tmp][j]].first > stop){ ans += (1<<j); tmp = up_min[tmp][j]; } } if(all[up_min[tmp][0]].first > stop){ std::cout<<-1<<std::endl; continue; } std::cout<<ans + 1<<std::endl; } } }
#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...
#Verdict Execution timeMemoryGrader output
Fetching results...