CF 1620 E Replace the Numbers 题解

题面

要求维护一个数组,支持两个操作:

  • \(x\) 加到数组尾部
  • 把当前数组里所有 \(x\) 换成 \(y\)
    输出所有操作后的结果。

题解

因为我们每次要对一把的相同的数进行改变,所以这里使用了一种整块移动的思想。令每个可能的值 \(x\) 是一个桶,然后桶里面可以装桶,那么每个桶收集的就是上次被替换之后到目前为止所有当前值为 \(x\) 的元素或桶(区别为是否有 child)。然后当替换时我们就把最外层的大桶直接套到被替换的大桶里即可。这里的桶其实就是个 vector,然后通过指针方便移动,而在最后则只需要把每个桶中桶拆开成大桶的值即可。

Code

#include <cstdio>
#include <vector>
const int MAXN=5e5+5;
struct Node {
    int val;
    std::vector<Node*> child;
};
Node* node[MAXN]; int t, op, x, y, ind; int arr[MAXN];
void dfs(Node* node) {
    if(!node->child.size()) {
        arr[node->val]=x;
        return;
    }
    for(auto n : node->child)
        dfs(n);
}
int main() {
    scanf("%d",&t);
    while(t--) {
        scanf("%d %d", &op, &x);
        if(op==1) {
            Node* n = new Node;
            n->val = ++ind;
            if(!node[x]) {
                node[x] = new Node;
                node[x]->val = x;
            }
            node[x]->child.push_back(n);
        } else {
            scanf("%d",&y);
            if(!node[x] || x==y)
                continue;
            if(!node[y]) {
                node[y] = new Node;
                node[y]->val = y;
            }
            node[y]->child.push_back(node[x]);
            node[x] = nullptr;
        }
    }
    for(int i=1;i<=5e5;i++)
        if(node[i]) {
            x=i;
            dfs(node[i]);
        }
    for(int i=1;i<=ind;i++)
        printf("%d ",arr[i]);
    return 0;
}
posted @ 2022-01-24 11:34  酷暑一夏1  阅读(80)  评论(0编辑  收藏  举报