题目
测试题目传送门 emmm,其实只写了一部分函数(就这还折腾了整整半天 ),其他的留坑吧= =,而且也没用指针写,常数也很大QAQ
Code
//By zuiyumeng
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define Re register
#define Ms(a,b) memset((a),(b),sizeof(a))
#define Fo(i,a,b) for(Re int i=(a),_=(b);i<=_;i++)
#define Ro(i,a,b) for(Re int i=(b),_=(a);i>=_;i--)
using namespace std;
inline int read() {
int x=0,f=1;char c=getchar();
while(!isdigit(c)) {if(c=='-')f=-f;c=getchar();}
while(isdigit(c)) x=(x<<1)+(x<<3)+c-48,c=getchar();
return x*f;
}
const int N=1e5+10;
int n,m;
int fdeg[N],fa[N];
bool vis[N];
struct Node{
int key,degree,fa,son,left,right;
bool deld;//该题特殊要求
}nd[N];
struct Heap{
int min,n;
}hep[N];
void insrt(int now,int u) {
Node &x=nd[u]; Heap &h=hep[now];
x.fa=0;
if(!h.min) {
x.left=x.right=u;
h.min=u;
} else {
Node &y=nd[h.min],&z=nd[y.right];
x.left=z.left; x.right=y.right;
y.right=z.left=u;
if(y.key>x.key||(y.key==x.key&&h.min>u)) h.min=u;
// ||后为该题特殊要求
}
h.n++;
}
Heap merge(int u,int v) {
Heap &h1=hep[u],&h2=hep[v],h;
Node &a1=nd[h1.min],&b1=nd[a1.right];
Node &a2=nd[h2.min],&b2=nd[a2.left];
b1.left=a2.left,b2.right=a1.right;
a1.right=h2.min,a2.left=h1.min;
h.min=h1.min;
if(!h1.min || (h2.min&&a2.key<a1.key)) h.min=h2.min;
h.n=h1.n+h2.n;
return h;
}
void link(int now,int u,int v) {
Node &x=nd[u],&y=nd[v];
nd[y.left].right=y.right;
nd[y.right].left=y.left;
if(x.son) {
Node &a=nd[x.son],&b=nd[a.right];
y.left=x.son,y.right=a.right;
a.right=v,b.left=v;
} else {
x.son=v;
y.left=y.right=v;
}
y.fa=u; x.degree++;
}
void consoldate(int now) {
Ms(fdeg,0);Ms(vis,0);
Heap &h=hep[now];
int cur=h.min;
while(!vis[cur]) {
int d=nd[cur].degree,nxt=nd[cur].right; vis[cur]=1;
while(fdeg[d]) {
Node &y=nd[fdeg[d]],&x=nd[cur];
if(x.key>y.key||(x.key==y.key&&cur>fdeg[d])) swap(cur,fdeg[d]);
// ||后为该题特殊要求
link(now,cur,fdeg[d]);
fdeg[d]=0; d++;
}
fdeg[d]=cur;
cur=nxt;
}
h.min=0;
Fo(i,0,ceil(log2((double)h.n))+1) if(fdeg[i]) {
int u=fdeg[i]; Node &x=nd[u];
insrt(now,u); h.n--;
}
}
int deleteMin(int now) {
Heap &h=hep[now];
Node &x=nd[h.min];
if(!h.min) return 0;
int cur=x.son;
Fo(i,1,x.degree) {
int nxt=nd[cur].left;
insrt(now,cur); h.n--;
nd[cur].fa=0;
cur=nxt;
}
nd[x.left].right=x.right;
nd[x.right].left=x.left;
x.deld=1; x.son=0;
if(x.right==h.min) h.min=0;
else {
h.min=x.right;
consoldate(now);
}
h.n--;
return x.key;
}
int getro(int x) {return fa[x]=fa[x]==x?x:getro(fa[x]);}//这个题得用并查集
int main() {
n=read();m=read();
Fo(i,1,n) nd[i].key=read(),insrt(i,i),fa[i]=i;
Fo(i,1,m) {
int opt=read();
if(opt==1) {
int x=read(),y=read();
if(nd[x].deld||nd[y].deld) continue;
int rx=getro(x),ry=getro(y);
if(rx==ry) continue;
if(rx>ry) swap(rx,ry);
hep[rx]=merge(rx,ry);
fa[ry]=rx;
} else {
int x=read();
if(nd[x].deld) {cout<<"-1"<<endl;continue;}
int rx=getro(x);
cout<<deleteMin(rx)<<endl;
}
}
return 0;
}