// 【模板】文艺平衡树
#include <cstdio>
#include <cstdlib>
#define lc son[p][0]
#define rc son[p][1]

const int N = 1e5 + 37;
int n, m, idx, root;
int son[N][2], val[N], siz[N], pri[N], tag[N];

void swap(int &x, int &y) {
    int z = x;
    x = y;
    y = z;
}

void up(int p) { siz[p] = siz[lc] + siz[rc] + 1; }

void down(int p) {
    if (!tag[p]) return;
    swap(son[p][0], son[p][1]);
    tag[lc] ^= 1, tag[rc] ^= 1;
    tag[p] = 0;
}

void split(int p, int v, int &l, int &r) {
    if (!p) {
        l = r = 0;
        return;
    }
    down(p);
    if (siz[lc] < v) {
        l = p;
        split(rc, v - siz[lc] - 1, rc, r);
    } else {
        r = p;
        split(lc, v, l, lc);
    }
}

int merge(int l, int r) {
    if (!l || !r) return l + r;
    if (pri[l] > pri[r]) {
        down(l);
        son[l][1] = merge(son[l][1], r);
        up(l);
        return l;
    } else {
        down(r);
        son[r][0] = merge(l, son[r][0]);
        up(r);
        return r;
    }
}

int insert(int v) {
    int p = ++idx, l, r;
    split(root, v, l, r);
    pri[p] = rand();
    val[p] = v;
    siz[p] = 1;
    root = merge(merge(l, p), r);
}

void dfs(int p) {
    if (!p) return;
    down(p);
    dfs(lc);
    printf("%d ", p);
    dfs(rc);
}

int main()
{
    scanf("%d %d", &n, &m);
    for (int i = 1; i <= n; i++) insert(i);

    for (int i = 1, ll, rr; i <= m; i++) {
        scanf("%d %d", &ll, &rr);
        int p, l, r;
        split(root, rr, l, r);
        split(l, ll - 1, l, p);
        tag[p] ^= 1;
        root = merge(merge(l, p), r);
    }

    dfs(root);
    return 0;
}

3 条评论

  • @ 2025-8-22 14:57:11
    #include <cstdio>
    #include <cstdlib>
    #define lc son[p][0]
    #define rc son[p][1]
    
    const int N = 1e5 + 37;
    int n, m, idx, root;
    int son[N][2], val[N], siz[N], pri[N], tag[N];
    
    void swap(int &x, int &y) {
        int z = x;
        x = y;
        y = z;
    }
    
    void up(int p) { siz[p] = siz[lc] + siz[rc] + 1; }
    
    void down(int p) {
        if (!tag[p]) return;
        swap(son[p][0], son[p][1]);
        tag[lc] ^= 1, tag[rc] ^= 1;
        tag[p] = 0;
    }
    
    void split(int p, int v, int &l, int &r) {
        if (!p) {
            l = r = 0;
            return;
        }
        down(p);
        if (siz[lc] < v) {
            l = p;
            split(rc, v - siz[lc] - 1, rc, r);
        } else {
            r = p;
            split(lc, v, l, lc);
        }
        up(p);
    }
    
    int merge(int l, int r) {
        if (!l || !r) return l + r;
        if (pri[l] > pri[r]) {
            down(l);
            son[l][1] = merge(son[l][1], r);
            up(l);
            return l;
        } else {
            down(r);
            son[r][0] = merge(l, son[r][0]);
            up(r);
            return r;
        }
    }
    
    void insert(int v) {
        int p = ++idx, l, r;
        split(root, v, l, r);
        pri[p] = rand();
        val[p] = v;
        siz[p] = 1;
        root = merge(merge(l, p), r);
    }
    
    void dfs(int p) {
        if (!p) return;
        down(p);
        dfs(lc);
        printf("%d ", p);
        dfs(rc);
    }
    
    int main()
    {
        scanf("%d %d", &n, &m);
        for (int i = 1; i <= n; i++) insert(i);
    
        for (int i = 1, ll, rr; i <= m; i++) {
            scanf("%d %d", &ll, &rr);
            int p, l, r;
            split(root, rr, l, r);
            split(l, ll - 1, l, p);
            tag[p] ^= 1;
            root = merge(merge(l, p), r);
        }
    
        dfs(root);
        return 0;
    }
    
    
    
    • @ 2025-8-22 14:54:48
      #include <cstdio>
      #include <cstdlib>
      #define lc son[p][0]
      #define rc son[p][1]
      const int N = 1e5 + 37;
      int n, m, idx, root;
      int son[N][2], val[N], siz[N], pri[N], tag[N];
      void swap(int &x, int &y) {
          int z = x;
          x = y;
          y = z;
      }
      void up(int p) { siz[p] = siz[lc] + siz[rc] + 1; }
      void down(int p) {
          if (!tag[p]) return;
          swap(son[p][0], son[p][1]);
          tag[lc] ^= 1, tag[rc] ^= 1;
          tag[p] = 0;
      }
      void split(int p, int v, int &l, int &r) {
          if (!p) {
              l = r = 0;
              return;
          }
          down(p);
          if (siz[lc] < v) {
              l = p;
              split(rc, v - siz[lc] - 1, rc, r);
              up(p); // 修改:在递归后更新
          } else {
              r = p;
              split(lc, v, l, lc);
              up(p); // 修改:在递归后更新
          }
      }
      int merge(int l, int r) {
          if (!l || !r) return l + r;
          if (pri[l] > pri[r]) {
              down(l);
              son[l][1] = merge(son[l][1], r);
              up(l);
              return l;
          } else {
              down(r);
              son[r][0] = merge(l, son[r][0]);
              up(r);
              return r;
          }
      }
      int insert(int v) {
          int p = ++idx;
          pri[p] = rand();
          val[p] = v;
          siz[p] = 1;
          int l, r;
          split(root, v, l, r); // 在位置 v 处分割?但这里的 v 是值,且作为大小,但当树较小时,会以完整大小分割
          root = merge(merge(l, p), r);
      }
      void dfs(int p) {
          if (!p) return;
          down(p);
          dfs(lc);
          printf("%d ", val[p]); // 输出值或 p 都可以,但更安全是输出 p
          // 但这里 val[p] 应该与 p 相同,输出 p 也可以
          dfs(rc);
      }
      int main()
      {
          scanf("%d %d", &n, &m);
          for (int i = 1; i <= n; i++) insert(i);
          for (int i = 1, ll, rr; i <= m; i++) {
              scanf("%d %d", &ll, &rr);
              int l, r, p;
              split(root, rr, l, r);
              split(l, ll - 1, l, p);
              tag[p] ^= 1;
              root = merge(merge(l, p), r);
          }
          dfs(root);
          return 0;
      }
      
      • @ 2025-8-22 14:37:44

        已经收到你的问题啦!马上处理

        ❤️ 1
        👍 1
        • 1