1 条题解

  • 0
    @ 2025-11-27 15:00:06

    🔍 题目核心思路分析

    问题理解

    题目描述了一个三叉树结构,其中每个非叶子节点有三个输入(来自子节点或外部输入),其输出由三个输入的多数表决决定(即1的数量多则输出1,否则输出0)。

    • 树结构:有n个非叶子节点(编号1~n),2n+1个叶子节点(编号n+1~3n+1)
    • 操作q次修改,每次翻转一个叶子节点的值(0变1,1变0),要求输出每次修改后根节点的输出

    关键观察

    1. 节点状态定义:对每个节点u,定义val[u]为其三个输入中1的个数

      • 节点输出:out[u] = 1 当且仅当 val[u] ≥ 2
      • 对于叶子节点,初始val值为2 * input(即0或2)
    2. 修改传播规律

      • 当叶子节点从0变为1时,只会影响从该叶子节点父节点开始向上连续val=1的链
      • 当叶子节点从1变为0时,只会影响从该叶子节点父节点开始向上**连续val=2的链`
      • 一旦遇到val不为1(或2)的节点,传播停止

    由于需要高效处理树上路径操作,选择使用LCT,复杂度O((n+q) log n)

    💡 LCT解法详细说明

    维护信息

    每个节点维护:

    • val:该节点三个输入中1的个数(0~3)
    • n1:当前splay子树中深度最大val ≠ 1的节点
    • n2:当前splay子树中深度最大val ≠ 2的节点
    • tag:懒标记,表示子树是否需要val翻转(1↔2)

    核心操作

    1. 初始建树:用拓扑排序计算每个节点的初始val

    2. 修改叶子节点x

      • 找到x的父节点f
      • 根据x是0→1还是1→0,确定要找n1[f]还是n2[f]
      • access(f)splay(f),找到链顶节点
      • 对受影响的部分打标记修改

    代码实现要点

    // 核心更新函数
    void pushup(int x) {
        // 优先右子树,然后当前节点,最后左子树
        n1[x] = n1[ch[x][1]];
        if (!n1[x]) n1[x] = (val[x] != 1) ? x : 0;
        if (!n1[x]) n1[x] = n1[ch[x][0]];
        
        n2[x] = n2[ch[x][1]]; 
        if (!n2[x]) n2[x] = (val[x] != 2) ? x : 0;
        if (!n2[x]) n2[x] = n2[ch[x][0]];
    }
    
    // 标记下传
    void pushdown(int x) {
        if (tag[x]) {
            if (ch[x][0]) update_node(ch[x][0], tag[x]);
            if (ch[x][1]) update_node(ch[x][1], tag[x]);
            tag[x] = 0;
        }
    }
    
    // 节点更新
    void update_node(int x, int d) {
        tag[x] += d;
        if (d == 1) { // 1→2
            if (val[x] == 1) val[x] = 2;
            else if (val[x] == 2) val[x] = 1;
        } else { // 2→1
            if (val[x] == 2) val[x] = 1;
            else if (val[x] == 1) val[x] = 2;
        }
        swap(n1[x], n2[x]);
    }
    

    🧮 复杂度分析

    • 预处理:O(n) 拓扑排序
    • 每次查询:O(log n) LCT操作
    • 总复杂度:O(n + q log n),可满足n,q ≤ 5×10⁵

    💎 总结

    本题的关键在于发现修改传播的连续性(只影响val=1或2的连续链),从而可以用LCT高效维护。需要注意的细节是叶子节点的val初始为0或2,而非0或1。

    • 1

    信息

    ID
    5586
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    1
    已通过
    1
    上传者