将操作序列反向,用并查集维护集合里最强的星球。
--------------
const int maxn=11000;
const int maxm=22000;
const int maxq=55000;
int n,m,Q;
int p[maxn];
int a[maxn];
int id[maxn];
int pa[maxn];
void makeset(int n){
for (int i=0;i<=n;i++) pa[i]=i;
}
int findset(int x){
if (x!=pa[x]) pa[x]=findset(pa[x]);
return pa[x];
}
void unionset(int x,int y){
x=findset(x);
y=findset(y);
if (x!=y) {
pa[x]=y;
if (a[x]>a[y]){
a[y]=a[x];
id[y]=id[x];
}
else if (a[y]==a[x]&&id[x]<id[y]){
id[y]=id[x];
}
}
}
struct Dat{
int tp,x,y;
};
Dat q[maxq];
Dat e[maxm];
vector<int>ans;
set< PII >seto;
char s[10];
int main(){
int cas=0;
while (~scanf("%d",&n)){
if (cas) printf("\n");
cas++;
rst(q);
rst(e);
ans.clear();
seto.clear();
makeset(n);
for (int i=0;i<n;i++){
scanf("%d",&p[i]);
a[i]=p[i];
id[i]=i;
}
scanf("%d",&m);
for (int i=0;i<m;i++) scanf("%d%d",&e[i].x,&e[i].y);
scanf("%d",&Q);
for (int i=0;i<Q;i++){
scanf("%s",s);
if (s[0]=='d'){
q[i].tp=0;
scanf("%d%d",&q[i].x,&q[i].y);
seto.insert(make_pair(q[i].x,q[i].y));
seto.insert(make_pair(q[i].y,q[i].x));
}
else if (s[0]=='q'){
q[i].tp=1;
scanf("%d",&q[i].x);
}
}
for (int i=0;i<m;i++){
if (seto.find(make_pair(e[i].x,e[i].y))==seto.end()){
unionset(e[i].x,e[i].y);
}
}
for (int i=Q-1;i>=0;i--){
if (q[i].tp){
int fa=findset(q[i].x);
if (a[fa]>p[q[i].x]) ans.push_back(id[fa]);// printf("%d\n",id[fa]);
else ans.push_back(-1);// printf("-1\n");
}
else{
unionset(q[i].x,q[i].y);
}
}
for (int i=sz(ans)-1;i>=0;i--){
printf("%d\n",ans[i]);
}
//printf("\n");
}
return 0;
}
--------------