NC210108. 罗马游戏
描述
输入描述
第一行一个整数n(1<=n<=1000000)。n表示士兵数,m表示总命令数。 第二行n个整数,其中第i个数表示编号为i的士兵的分数。(分数都是[0..10000]之间的整数) 第三行一个整数m(1<=m<=100000) 第3+i行描述第i条命令。命令为如下两种形式: 1. M i j 2. K i
输出描述
如果命令是Kill,对应的请输出被杀人的分数。(如果这个人不存在,就输出0)
示例1
输入:
5 100 90 66 99 10 7 M 1 5 K 1 K 1 M 2 3 M 3 4 K 5 K 4
输出:
10 100 0 66
C++ 解法, 执行用时: 549ms, 内存消耗: 21424K, 提交时间: 2022-07-27 17:38:37
#include<iostream> using namespace std; int n,m,a[1000010],d[1000010],ls[1000010],rs[1000010],f[1000010],x,y; bool b[1000010]; char z; int find(int x){ if(f[x]==x) return x; return f[x]=find(f[x]); } int merge(int x,int y){ if(!x||!y) return x+y; if(a[x]>a[y]||(a[x]==a[y]&&x>y)) swap(x,y); rs[x]=merge(rs[x],y); if(d[ls[x]]<d[rs[x]]) swap(ls[x],rs[x]); d[x]=d[rs[x]]+1; return x; } int main(){ cin>>n; d[0]=-1; for(int i=1;i<=n;i++){ f[i]=i; cin>>a[i]; } cin>>m; while(m--){ cin>>z; if(z=='M'){ cin>>x>>y; if(b[x]||b[y]) continue; x=find(x); y=find(y); if(x==y) continue; f[x]=f[y]=merge(x,y); } else if(z=='K'){ cin>>x; if(b[x]){ cout<<0<<endl; continue; } x=find(x); cout<<a[x]<<endl; b[x]=1; f[x]=f[ls[x]]=f[rs[x]]=merge(ls[x],rs[x]); ls[x]=rs[x]=d[x]=0; } } return 0; }