将操作序列反向,用并查集维护集合里最强的星球。
--------------
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(" "); 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 ",id[fa]); else ans.push_back(-1);// printf("-1 "); } else{ unionset(q[i].x,q[i].y); } } for (int i=sz(ans)-1;i>=0;i--){ printf("%d ",ans[i]); } //printf(" "); } return 0; }
--------------