zoukankan      html  css  js  c++  java
  • 飘扬的旗帜

    我也不知道哪里蒯来的题。反正二分 + 2-sat + 线段树优化连边就完事了。

    注意答案可能为0..

      1 #include <bits/stdc++.h>
      2 
      3 const int N = 100010;
      4 
      5 struct Edge {
      6     int nex, v;
      7 }edge[3000010]; int tp;
      8 
      9 struct Node {
     10     int x, f;
     11     Node(int X = 0, int F = 0) {
     12         x = X;
     13         f = F;
     14     }
     15 };
     16 
     17 int e[N], num, dfn[N], low[N], X[N], xx, tot, n, fr[N], scc_cnt, ls[N], rs[N];
     18 std::vector<Node> v[N];
     19 int stk[N], top, rt, A[N],  B[N];
     20 
     21 inline void add(int x, int y) {
     22     tp++;
     23     edge[tp].v = y;
     24     edge[tp].nex = e[x];
     25     e[x] = tp;
     26     return;
     27 }
     28 
     29 inline void clear() {
     30     memset(e + 1, 0, tot * sizeof(int));
     31     memset(dfn + 1, 0, tot * sizeof(int));
     32     memset(fr + 1, 0, tot * sizeof(int));
     33     tp = top = num = scc_cnt = 0;
     34     return;
     35 }
     36 
     37 void tarjan(int x) {
     38     low[x] = dfn[x] = ++num;
     39     stk[++top] = x;
     40     for(int i = e[x]; i; i = edge[i].nex) {
     41         int y = edge[i].v;
     42         if(!dfn[y]) {
     43             tarjan(y);
     44             low[x] = std::min(low[x], low[y]);
     45         }
     46         else if(!fr[y]) {
     47             low[x] = std::min(low[x], dfn[y]);
     48         }
     49     }
     50     if(low[x] == dfn[x]) {
     51         ++scc_cnt;
     52         int y;
     53         do {
     54             y = stk[top];
     55             top--;
     56             fr[y] = scc_cnt;
     57         } while(y != x);
     58     }
     59     return;
     60 }
     61 
     62 void Add(int L, int R, int v, int l, int r, int &o) {
     63     if(!o) o = ++tot;
     64     if(L <= l && r <= R) {
     65         add(v, o);
     66         return;
     67     }
     68     int mid = (l + r) >> 1;
     69     if(L <= mid) Add(L, R, v, l, mid, ls[o]);
     70     if(mid < R) Add(L, R, v, mid + 1, r, rs[o]);
     71     return;
     72 }
     73 
     74 void build(int f, int l, int r, int &o) {
     75     if(!o) o = ++tot;
     76     if(f) add(f, o);
     77     if(l == r) {
     78         for(int i = 0; i < (int)v[r].size(); i++) {
     79             if(v[r][i].f) {
     80                 add(o, v[r][i].x);
     81             }
     82             else {
     83                 add(o, v[r][i].x + n);
     84             }
     85         }
     86         return;
     87     }
     88     int mid = (l + r) >> 1;
     89     build(o, l, mid, ls[o]);
     90     build(o, mid + 1, r, rs[o]);
     91     return;
     92 }
     93 
     94 inline bool check(int k) {
     95 
     96     clear();
     97     for(int i = 1; i <= n; i++) {
     98         int l = std::lower_bound(X + 1, X + xx + 1, X[A[i]] - k) - X;
     99         int r = std::upper_bound(X + 1, X + xx + 1, X[A[i]] + k) - X - 1;
    100         int mid = A[i];
    101         if(l < mid) {
    102             Add(l, mid - 1, i, 1, xx, rt);
    103         }
    104         if(mid < r) {
    105             Add(mid + 1, r, i, 1, xx, rt);
    106         }
    107         for(int j = 0; j < (int)v[mid].size(); j++) {
    108             if(v[mid][j].x == i) continue;
    109             if(v[mid][j].f) {
    110                 add(i, v[mid][j].x);
    111             }
    112             else {
    113                 add(i, v[mid][j].x + n);
    114             }
    115         }
    116         l = std::lower_bound(X + 1, X + xx + 1, X[B[i]] - k) - X;
    117         r = std::upper_bound(X + 1, X + xx + 1, X[B[i]] + k) - X - 1;
    118         mid = B[i];
    119         if(l < mid) {
    120             Add(l, mid - 1, i + n, 1, xx, rt);
    121         }
    122         if(mid < r) {
    123             Add(mid + 1, r, i + n, 1, xx, rt);
    124         }
    125         for(int j = 0; j < (int)v[mid].size(); j++) {
    126             if(v[mid][j].x == i) continue;
    127             if(v[mid][j].f) {
    128                 add(i + n, v[mid][j].x);
    129             }
    130             else {
    131                 add(i + n, v[mid][j].x + n);
    132             }
    133         }
    134     }
    135     build(0, 1, xx, rt);
    136     for(int i = 1; i <= tot; i++) {
    137         if(!dfn[i]) {
    138             tarjan(i);
    139         }
    140     }
    141     for(int i = 1; i <= n; i++) {
    142         if(fr[i] == fr[i + n]) return 0;
    143     }
    144     return 1;
    145 }
    146 
    147 int main() {
    148 
    149     scanf("%d", &n);
    150     tot = n << 1;
    151     for(int i = 1; i <= n; i++) {
    152         scanf("%d%d", &A[i], &B[i]);
    153         X[++xx] = A[i]; X[++xx] = B[i];
    154     }
    155     std::sort(X + 1, X + xx + 1);
    156     xx = std::unique(X + 1, X + xx + 1) - X - 1;
    157     for(int i = 1; i <= n; i++) {
    158         A[i] = std::lower_bound(X + 1, X + xx + 1, A[i]) - X;
    159         B[i] = std::lower_bound(X + 1, X + xx + 1, B[i]) - X;
    160         v[A[i]].push_back(Node(i, 0));
    161         v[B[i]].push_back(Node(i, 1));
    162     }
    163 
    164     int l = -1, r = X[xx] - X[1];
    165     while(l < r) {
    166         int mid = (l + r + 1) >> 1;
    167         if(check(mid)) {
    168              l = mid;
    169          }
    170          else {
    171              r = mid - 1;
    172          }
    173     }
    174 
    175     printf("%d
    ", r + 1);
    176     return 0;
    177 }
    AC代码

    我这个写法不对,如果离散化了就不能暴力处理单个位置的其他边,因为可能会被卡成n²。正确的方法是不离散化或者对每个位置再用一个前后缀优化连边。

  • 相关阅读:
    组件
    Django
    面向对象
    异常处理
    模块1
    Java中权限设置
    java反射机制
    JavaScript提高篇之面向对象之单利模式工厂模型构造函数原型链模式
    JavaScript提高篇之预解释作用域以及this原理及其应用
    js-引用类型-Array
  • 原文地址:https://www.cnblogs.com/huyufeifei/p/10599853.html
Copyright © 2011-2022 走看看