At411 D - Conflict 2
D.Conflict 2
题意简述
有 \(N\) 个电脑.一台服务器 和 每台 电脑 都有一个字符串, 一开始每个字符串都是空的.
现有 \(Q\) 次 查询。每个查询都是以下形式:
1 p
: 把第 p 个电脑的字符串换成服务器字符串.2 p s
: 在第 p 个电脑末尾添加字符串.3 p
: 把服务器字符串换成第 p 个电脑的字符串.
请输出最后服务器所在字符串.
解题思路
直接模拟炸了,想要优化,
考虑最后的结果字符串是由什么构成的?本质上若干次2号操作的一个链构成,
考虑维护2号操作记录的字符串,以及每一次2号操作的版本,再从结果溯源,
由记录的版本号从结果倒推即可。
AC code
#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
typedef long long ll;
const int N=2e5+5;
int ver[N];//ver[0]是服务器版本号
int pre[N],m;
string _2[N];
int main(){
cin.tie(0)->ios::sync_with_stdio(false);
int n,q;cin>>n>>q;
for(int i=1;i<=q;i++){
int op,x;
cin>>op>>x;
if(op==1) ver[x]=ver[0];//第x个电脑版本继承服务器版本
else if(op==2){
++m;
cin>>_2[m];//第m个版本添加的字符串
pre[m]=ver[x];//第m个版本前一个版本
ver[x]=m;
}
else if(op==3) ver[0]=ver[x];//服务器版本继承第x个电脑版本
}
int x=ver[0];
string ans;
while(x){
reverse(_2[x].begin(),_2[x].end());
ans+=_2[x];
x=pre[x];//成为上一个版本
}
reverse(ans.begin(),ans.end());
cout<<ans<<endl;
return 0;
}