• AT2534 港湾設備 (Port Facility)


    题目链接

    主席树好难调,简要记录以下正解:

    显然可以看成连边跑黑白染色,但是边数太多没法连。

    于是可以用主席树优化建图

    我们先考虑用一个栈来记录还没扫到右端点的左端点。这样的话当前如果扫到一个右端点,找到其对应左端点后栈内从左端点到最后都是和它有交叉的线段,都需要连边,然后将当前左端点删除,删除方法用并查集(类似LCT的缩点)。发现那个线段一定会被染成相同的染色,否则无解,于是我们这次连以后再遇到这些点只需再连其中一个(随意“缩点”)即可,这个也可以用并查集或者直接记一个 nxt 数组即可。

    关键代码:

    int col[N];
    void dfs(int cur) {
      for (int i = head[cur]; i; i = e[i].nxt) {
        int to = e[i].to;
        if (col[to] == -1)  col[to] = col[cur] ^ 1, dfs(to);
        else if (col[to] == col[cur]) { puts("0"); exit(0); }
      }
    }
    int main() {
      read(n);
      for (int i = 1; i <= n; ++i) {
        int x, y; read(x), read(y);
        h[x] = i; h[y] = i;
      }
      for (int i = 1; i <= n + n; ++i)  fa[i] = i, nxt[i] = i + 1;
      for (int i = 1; i <= n + n; ++i) {
        int nw = h[i];
        int l = pos[nw];
        if (!l) { stk[++stop] = nw; pos[nw] = stop; continue; }
        fa[l] = l + 1;
        for (int j = find(fa[l]), tmp; j <= stop; tmp = j, j = find(nxt[j]), nxt[tmp] = stop + 1)
          addedge(stk[j], nw), addedge(nw, stk[j]);
      }
      memset(col, -1, sizeof(col));
      int ans = 1;
      for (int i = 1; i <= n; ++i) if (col[i] == -1)
        col[i] = 0, dfs(i), ans = (ans << 1) % P;
      printf("%d
    ", ans);
      return 0;
    }
    
  • 相关阅读:
    Javascript异步编程的4种方法(阮一峰)
    vue 要点
    npm指南
    http请求状态及其含义表
    IOS 7层协议
    js模块化
    UITouch触摸事件
    UIGestureRecognizer手势识别
    UISegmentControl 、UIStepper
    UINavigationController
  • 原文地址:https://www.cnblogs.com/JiaZP/p/13683125.html
Copyright © 2020-2023  润新知