Advertisement
lukadupli

Flags

Feb 19th, 2023 (edited)
30
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.24 KB | Source Code | 0 0
  1. #include <bits/stdc++.h>
  2.  
  3. #define X first
  4. #define Y second
  5.  
  6. using namespace std;
  7.  
  8. typedef pair<int, int> pii;
  9.  
  10. const int OFFSET = 1 << 15, INF = 1e9 + 5;
  11.  
  12. int n, helper[OFFSET], opposite[OFFSET];
  13. vector<pii> pos;
  14. vector<int> adj[2 * OFFSET], adjrev[2 * OFFSET];
  15.  
  16. pii nodeval[2 * OFFSET];
  17. void build(int node = 1){
  18.     if(node >= OFFSET){
  19.         int ind = node - OFFSET;
  20.         if(ind < pos.size()) nodeval[node] = {pos[ind].X, pos[ind].X};
  21.         return;
  22.     }
  23.  
  24.     adj[node].push_back(2 * node);
  25.     adj[node].push_back(2 * node + 1);
  26.  
  27.     adjrev[2 * node].push_back(node);
  28.     adjrev[2 * node + 1].push_back(node);
  29.  
  30.     build(2 * node);
  31.     build(2 * node + 1);
  32.  
  33.     nodeval[node] = {
  34.         min(nodeval[2 * node].X, nodeval[2 * node + 1].X),
  35.         max(nodeval[2 * node].Y, nodeval[2 * node + 1].Y) };
  36. }
  37.  
  38. void connect(int thing, int lo, int hi, int node = 1, int l = 0, int r = OFFSET){
  39.     if(l >= 2 * n) return;
  40.     if(nodeval[node].X >= lo && nodeval[node].Y <= hi && (opposite[thing - OFFSET] < l || opposite[thing - OFFSET] >= r)){
  41.         adj[thing].push_back(node);
  42.         adjrev[node].push_back(thing);
  43.         return;
  44.     }
  45.     if(nodeval[node].X > hi || nodeval[node].Y < lo) return;
  46.     if(r - l == 1) return;
  47.  
  48.     int m = (l + r) / 2;
  49.     connect(thing, lo, hi, 2 * node, l, m);
  50.     connect(thing, lo, hi, 2 * node + 1, m, r);
  51. }
  52.  
  53. vector<int> scc_stack;
  54. bool bio[2 * OFFSET];
  55. void scc_dfs1(int node){
  56.     if(bio[node]) return;
  57.     bio[node] = true;
  58.  
  59.     for(auto nxt : adj[node]) scc_dfs1(nxt);
  60.  
  61.     scc_stack.push_back(node);
  62. }
  63.  
  64. int scc[2 * OFFSET];
  65. void scc_dfs2(int node, int comp){
  66.     if(scc[node]) return;
  67.     scc[node] = comp;
  68.  
  69.     for(auto nxt : adjrev[node]) scc_dfs2(nxt, comp);
  70. }
  71.  
  72. void cleanup(){
  73.     for(int i = 0; i < 2 * n; i++){
  74.         adj[OFFSET + i].clear();
  75.     }
  76.  
  77.     for(int i = 1; i < 2 * OFFSET; i++){
  78.         adjrev[i].clear();
  79.         if(i > 1) adjrev[i].push_back(i / 2);
  80.     }
  81.  
  82.     memset(bio, 0, sizeof bio);
  83.     memset(scc, 0, sizeof scc);
  84.     scc_stack.clear();
  85. }
  86.  
  87. bool evaluate(int dist){
  88.     cleanup();
  89.  
  90.     for(int i = 0; i < 2 * n; i++) connect(OFFSET + opposite[i], pos[i].X - dist + 1, pos[i].X + dist - 1);
  91.  
  92.     scc_dfs1(1);
  93.     reverse(scc_stack.begin(), scc_stack.end());
  94.  
  95.     int comp = 0;
  96.     for(auto node : scc_stack){
  97.         if(scc[node] == 0) scc_dfs2(node, ++comp);
  98.     }
  99.  
  100.     for(int i = 0; i < 2 * n; i++){
  101.         if(scc[OFFSET + i] == scc[OFFSET + opposite[i]]) return false;
  102.     }
  103.  
  104.     return true;
  105. }
  106.  
  107. int main()
  108. {
  109.     ios_base::sync_with_stdio(0);
  110.     cin.tie(0);
  111.  
  112.     cin >> n;
  113.     for(int i = 0; i < n; i++){
  114.         int a, b;
  115.         cin >> a >> b;
  116.  
  117.         pos.push_back({a, i});
  118.         pos.push_back({b, i});
  119.     }
  120.  
  121.     sort(pos.begin(), pos.end());
  122.     memset(helper, -1, sizeof helper);
  123.     for(int i = 0; i < pos.size(); i++){
  124.         if(helper[pos[i].Y] == -1) helper[pos[i].Y] = i;
  125.         else{
  126.             opposite[i] = helper[pos[i].Y];
  127.             opposite[helper[pos[i].Y]] = i;
  128.         }
  129.     }
  130.  
  131.     build();
  132.  
  133.     int l = 0, r = INF;
  134.     while(r > l){
  135.         int m = (l + r + 1) / 2;
  136.  
  137.         if(evaluate(m)) l = m;
  138.         else r = m - 1;
  139.     }
  140.  
  141.     cout << l << '\n';
  142.  
  143.     return 0;
  144. }
  145.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement