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;
}
无特别声明的情况下,本文为原创文章,允许转载,采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。
在声明禁止转载的情况下,请勿转载;若本文章为转载的文章,版权归原作者所有。
如果您觉得本文写得好,请点击下方的推荐按钮~若您有任何建议和指正,请在下方留言,对于您的指正将不胜感激。
在声明禁止转载的情况下,请勿转载;若本文章为转载的文章,版权归原作者所有。
如果您觉得本文写得好,请点击下方的推荐按钮~若您有任何建议和指正,请在下方留言,对于您的指正将不胜感激。