# 配对堆学习笔记

## 配对堆学习笔记

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int x=0,pos=1;char ch=getchar();
for(;!isdigit(ch);ch=getchar()) if(ch=='-') pos=0;
for(;isdigit(ch);ch=getchar()) x=(x<<1)+(x<<3)+ch-'0';
return pos?x:-x;
}
#define ll long long
#define FOR(i,a,b) for(int i=a;i<=b;i++)
const int N = 1e5+200;
int f[N];
int gf(int x){
if(f[x]==x) return x;
else return f[x]=gf(f[x]);
}
int nex[N],son[N];int cnt;ll val[N];
nex[v]=son[u];son[u]=v;
}
int merge(int u,int v){//小根堆
if(!u||!v) return u^v;
}
int merges(int u){//把u和u的兄弟两两配对，merge到一起
if(!u) return 0; if(!nex[u]) return u;
int v1=nex[u],v2=nex[v1];
nex[u]=nex[v1]=0;return merge(merge(u,v1),merges(v2));
}
/*
void dfs(int u){
ans[++top]=val[u];
for(int i=son[u];i;i=nex[i]) dfs(i);
}*/
struct heap{
int rt;
void push(ll x){val[++cnt]=x;rt=merge(rt,cnt);}
ll top(){return val[rt];}
void pop(){rt=merges(son[rt]);}
void join(int now){rt=merge(rt,now);}
}h[N];
int main(){
FOR(i,1,n){
}
FOR(i,1,m){
if(opt==1){
if(val[x]==-1||val[y]==-1||fu==fv) continue;
f[fv]=fu;
h[fu].join(h[fv].rt);
}else{
if(val[x]==-1) printf("-1\n");
else{
int fu=gf(x);printf("%d\n",h[fu].top());val[h[fu].rt]=-1;h[fu].pop();
}
}
}
return 0;
}

### 例题 洛谷P3642 [APIO2016]烟火表演

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int x=0,pos=1;char ch=getchar();
for(;!isdigit(ch);ch=getchar()) if(ch=='-') pos=0;
for(;isdigit(ch);ch=getchar()) x=(x<<1)+(x<<3)+ch-'0';
return pos?x:-x;
}
#define ll long long
#define FOR(i,a,b) for(int i=a;i<=b;i++)
#define ROF(i,a,b) for(int i=a;i>=b;--i)
const int N = 6e6+200;
int f[N];
int gf(int x){
if(f[x]==x) return x;
else return f[x]=gf(f[x]);
}
int nex[N],son[N],d[N];int cnt;ll val[N],w[N];
nex[v]=son[u];son[u]=v;
}
int merge(int u,int v){//大根堆
if(!u||!v) return u^v;
}
int merges(int u){//把u和u的兄弟两两配对，merge到一起
if(!u) return 0; if(!nex[u]) return u;
int v1=nex[u],v2=nex[v1];
nex[u]=nex[v1]=0;return merge(merge(u,v1),merges(v2));
}
ll ans[N],top=0;
void dfs(int u){
ans[++top]=val[u];
for(int i=son[u];i;i=nex[i]) dfs(i);
}
struct heap{
int rt;
void push(ll x){val[++cnt]=x;rt=merge(rt,cnt);}
ll top(){return val[rt];}
void pop(){rt=merges(son[rt]);}
void join(int now){rt=merge(rt,now);}
}h[N];
int main(){
ll s0=0;
FOR(i,2,n+m){
}
ROF(i,n+m,2){
ll l=0,r=0;
while(d[i]){
d[i]--;r=h[i].top();h[i].pop();
}l=h[i].top();h[i].pop();
h[i].push(l+w[i]);h[i].push(r+w[i]);
h[f[i]].join(h[i].rt);
}
dfs(h[1].rt);
sort(ans+1,ans+top+1);top-=d[1];
FOR(i,0,top-1){
s0-=1ll*(top-i)*(ans[i+1]-ans[i]);
}
printf("%lld\n",s0);
return 0;
}
posted @ 2021-01-12 15:54  lcyfrog  阅读(48)  评论(0编辑  收藏