如题,一开始有N个小根堆,每个堆包含且仅包含一个数。接下来需要支持两种操作:
操作1: 1 x y 将第x个数和第y个数所在的小根堆合并(若第x或第y个数已经被删除或第x和第y个数在用一个堆内,则无视此操作)
操作2: 2 x 输出第x个数所在的堆最小数,并将其删除(若第x个数已经被删除,则输出-1并无视删除操作)
输入格式:
第一行包含两个正整数N、M,分别表示一开始小根堆的个数和接下来操作的个数。
第二行包含N个正整数,其中第i个正整数表示第i个小根堆初始时包含且仅包含的数。
接下来M行每行2个或3个正整数,表示一条操作,格式如下:
操作1 : 1 x y
操作2 : 2 x
输出格式:
输出包含若干行整数,分别依次对应每一个操作2所得的结果。
当堆里有多个最小值时,优先删除原序列的靠前的,否则会影响后续操作1导致WA。
时空限制:1000ms,128M
数据规模:
对于30%的数据:N<=10,M<=10
对于70%的数据:N<=1000,M<=1000
对于100%的数据:N<=100000,M<=100000
样例说明:
初始状态下,五个小根堆分别为:{1}、{5}、{4}、{2}、{3}。
第一次操作,将第1个数所在的小根堆与第5个数所在的小根堆合并,故变为四个小根堆:{1,3}、{5}、{4}、{2}。
第二次操作,将第2个数所在的小根堆与第5个数所在的小根堆合并,故变为三个小根堆:{1,3,5}、{4}、{2}。
第三次操作,将第2个数所在的小根堆的最小值输出并删除,故输出1,第一个数被删除,三个小根堆为:{3,5}、{4}、{2}。
第四次操作,将第4个数所在的小根堆与第2个数所在的小根堆合并,故变为两个小根堆:{2,3,5}、{4}。
第五次操作,将第2个数所在的小根堆的最小值输出并删除,故输出2,第四个数被删除,两个小根堆为:{3,5}、{4}。
故输出依次为1、2。
1 #include<bits/stdc++.h>> 2 using namespace std; 3 const int N=100010; 4 int n,m,val[N],ch[N][2],f[N],d[N],a,x,y; 5 inline int read(){ 6 int res=0,f=1; 7 char ch=getchar(); 8 while (ch<‘0‘||ch>‘9‘){ 9 if (ch==‘-‘){ 10 f=-f; 11 } 12 ch=getchar(); 13 } 14 while (isdigit(ch)){ 15 res=res*10+ch-‘0‘; 16 ch=getchar(); 17 } 18 return res*f; 19 } 20 inline int merge(int x,int y) 21 { 22 if (x==0||y==0) 23 { 24 return x+y; 25 } 26 if (val[x]>val[y]||(val[x]==val[y]&&x>y)) 27 { 28 swap(x,y); 29 } 30 ch[x][1]=merge(ch[x][1],y); 31 f[ch[x][1]]=x; 32 if (d[ch[x][0]]<d[ch[x][1]]) 33 { 34 swap(ch[x][0],ch[x][1]); 35 } 36 d[x]=d[ch[x][1]]+1; 37 return x; 38 } 39 40 inline int get(int x) 41 { 42 while (f[x]) 43 { 44 x=f[x]; 45 } 46 return x; 47 } 48 49 inline void pop(int x) 50 { 51 val[x]=-1; 52 f[ch[x][0]]=f[ch[x][1]]=0; 53 merge(ch[x][0],ch[x][1]); 54 } 55 56 int main() 57 { 58 n=read();m=read(); 59 d[0]=-1; 60 for (int i=1; i<=n; i++) 61 { 62 val[i]=read(); 63 } 64 for (int i=1; i<=m; i++) 65 { 66 a=read(); 67 if (a==1) 68 { 69 x=read();y=read(); 70 if(val[x]==-1||val[y]==-1) 71 { 72 continue; 73 } 74 if (x==y) 75 { 76 continue; 77 } 78 int f1=get(x),f2=get(y); 79 merge(f1,f2); 80 } 81 else 82 { 83 x=read(); 84 if (val[x]==-1) 85 { 86 printf("-1\n"); 87 } 88 else 89 { 90 int f1=get(x); 91 printf("%d\n",val[f1]); 92 pop(f1); 93 } 94 } 95 } 96 }
原文:https://www.cnblogs.com/Accpted/p/11213269.html