题意:
解法:
离线可以将删边变为逆序加边.
但是发现查询必须顺序,怎么办呢?
可以建立重构树维护图连通性,
具体做法是当从后向前枚举加边操作时,
假设要加的边是(a,b),如果不联通,
那么新建节点p,令p为a和b的父节点,
如果此时要查询与点a联通的点权最大值,
可以转化为子树p下的点权最大值,变成子树问题了.
子树问题可以dfs序建线段树做.
建完图之后正序进行操作1即可.
ps:
重构树巧妙的记录了离线状态下,
图各版本的连通性.
code:
#include <bits/stdc++.h>
using namespace std;
const int maxm=1e6+5;
struct QQ{
int op,x;
}Q[maxm];
struct EE{
int a,b;
}E[maxm];
struct PI{
int v,id;
bool operator<(const PI& a)const{
return v<a.v;
}
};
int head[maxm],nt[maxm],to[maxm],cnt;
int L[maxm],R[maxm],rk[maxm],idx;
int pre[maxm],tot;
int mark[maxm];
int del[maxm];
int v[maxm];
int n,m,q;
struct Tree{
PI a[maxm<<2];
inline void pp(int node){
a[node]=max(a[node*2],a[node*2+1]);
}
void build(int l,int r,int node){
if(l==r){
a[node]={v[rk[l]],l};
return ;
}
int mid=(l+r)/2;
build(l,mid,node*2);
build(mid+1,r,node*2+1);
pp(node);
}
void update(int x,int l,int r,int node){
if(l==r){
a[node].v=0;
return ;
}
int mid=(l+r)/2;
if(x<=mid)update(x,l,mid,node*2);
else update(x,mid+1,r,node*2+1);
pp(node);
}
PI ask(int st,int ed,int l,int r,int node){
if(st<=l&&ed>=r)return a[node];
int mid=(l+r)/2;
PI ans={-1,-1};
if(st<=mid)ans=max(ans,ask(st,ed,l,mid,node*2));
if(ed>mid)ans=max(ans,ask(st,ed,mid+1,r,node*2+1));
return ans;
}
}T;
int ffind(int x){
return pre[x]==x?x:pre[x]=ffind(pre[x]);
}
void add(int x,int y){
cnt++;nt[cnt]=head[x];head[x]=cnt;to[cnt]=y;
}
void dfs(int x){
L[x]=++idx;rk[idx]=x;
for(int i=head[x];i;i=nt[i]){
int v=to[i];dfs(v);
}
R[x]=idx;
}
void solve(){
cin>>n>>m>>q;
for(int i=1;i<=n;i++)cin>>v[i];
for(int i=1;i<=m;i++)cin>>E[i].a>>E[i].b;
for(int i=1;i<=q;i++){
cin>>Q[i].op>>Q[i].x;
if(Q[i].op==2)del[Q[i].x]=1;
}
for(int i=1;i<=n;i++)pre[i]=i,tot=i;
for(int i=1;i<=m;i++){
if(!del[i]){
int x=ffind(E[i].a),y=ffind(E[i].b);
if(x!=y){
pre[x]=y;
add(y,x);
}
}
}
for(int i=q;i>=1;i--){
if(Q[i].op==1)Q[i].x=ffind(Q[i].x);
else{
int x=ffind(E[Q[i].x].a),y=ffind(E[Q[i].x].b);
if(x!=y){
++tot;
pre[x]=pre[y]=pre[tot]=tot;
add(tot,x);add(tot,y);
}
}
}
for(int i=1;i<=tot;i++){//dfs序
int x=ffind(i);
if(!mark[x]){
mark[x]=1;
dfs(x);
}
}
T.build(1,tot,1);
for(int i=1;i<=q;i++){
if(Q[i].op==1){
PI ans=T.ask(L[Q[i].x],R[Q[i].x],1,tot,1);
cout<<ans.v<<endl;
T.update(ans.id,1,tot,1);
}
}
}
signed main(){
ios::sync_with_stdio(0);cin.tie(0);
solve();
return 0;
}