luogu4197 Peaks (kruskal重构树+主席树)

按照边权排序建出kruskal重构树,每次就变成了先找一个权值<=x的最远的祖先,然后看这个子树的第k小。离散化一下,在dfs序上做主席树即可

而且只需要建叶节点的主席树

注意输出的是第k小点的高度值

  1 #include<bits/stdc++.h>
  2 #define pa pair<int,int>
  3 #define ll long long
  4 using namespace std;
  5 const int maxn=1e5+10,maxm=5e5+10;
  6 
  7 inline ll rd(){
  8     ll x=0;char c=getchar();int neg=1;
  9     while(c<'0'||c>'9'){if(c=='-') neg=-1;c=getchar();}
 10     while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
 11     return x*neg;
 12 }
 13 
 14 struct Edge{
 15     int a,b,l;
 16 }eg[maxm];
 17 pa st[maxn];
 18 int N,M,Q,L,h[maxn<<1];
 19 int fa[maxn<<1],source[maxn];
 20 int tf[maxn<<1][20],ch[maxn<<1][2],pct;
 21 int dfn[maxn<<1][2],tot;
 22 int root[maxn],ztr[maxn*25],zch[maxn*25][2],zct;
 23 
 24 inline int getf(int x){
 25     return x==fa[x]?x:fa[x]=getf(fa[x]);
 26 }
 27 
 28 inline bool cmp(Edge a,Edge b){
 29     return a.l<b.l;
 30 }
 31 
 32 void insert(int pre,int &now,int l,int r,int x){
 33     now=++zct;ztr[now]=ztr[pre]+1;
 34     if(l<r){
 35         int m=l+r>>1;
 36         if(x<=m) zch[now][1]=zch[pre][1],insert(zch[pre][0],zch[now][0],l,m,x);
 37         else zch[now][0]=zch[pre][0],insert(zch[pre][1],zch[now][1],m+1,r,x);
 38     }
 39 }
 40 int query(int pre,int now,int l,int r,int k){
 41 //    printf("%d %d %d
",l,r,k);
 42     if(l==r) return l;
 43     int w=ztr[zch[now][0]]-ztr[zch[pre][0]];
 44     int m=l+r>>1;
 45     if(w>=k) return query(zch[pre][0],zch[now][0],l,m,k);
 46     else return query(zch[pre][1],zch[now][1],m+1,r,k-w);
 47 }
 48 
 49 void dfs(int x){
 50 //    printf("%d %d %d %d
",x,tf[x][0],ch[x][0],ch[x][1]);
 51     for(int i=1;tf[x][i-1]&&tf[tf[x][i-1]][i-1];i++){
 52         tf[x][i]=tf[tf[x][i-1]][i-1];
 53     }
 54     if((!ch[x][0])&&(!ch[x][1])){
 55         dfn[x][0]=dfn[x][1]=++tot;
 56         insert(root[tot-1],root[tot],1,L,h[x]);
 57     }else{
 58         dfn[x][0]=tot+1;
 59         dfs(ch[x][0]);dfs(ch[x][1]);
 60         dfn[x][1]=tot;
 61     }
 62 }
 63 
 64 int find(int x,int y){
 65     for(int i=19;i>=0;i--){
 66         if(tf[x][i]&&h[tf[x][i]]<=y) x=tf[x][i];
 67     }return x;
 68 }
 69 
 70 int main(){
 71     //freopen("4197.in","r",stdin);
 72     int i,j,k;
 73     N=rd(),M=rd(),Q=rd();
 74     for(i=1;i<=N;i++) st[i]=make_pair(rd(),i);
 75     sort(st+1,st+N+1);
 76     for(i=1,j=0;i<=N;i++){
 77         if(st[i].first!=st[i-1].first) j++;
 78         h[st[i].second]=j;source[j]=st[i].first;
 79     }L=j;
 80     for(i=1;i<=M;i++){
 81         int a=rd(),b=rd(),c=rd();
 82         eg[i].a=a;eg[i].b=b;eg[i].l=c;
 83     }
 84     sort(eg+1,eg+M+1,cmp);
 85     for(i=1;i<=N*2;i++) fa[i]=i;
 86     pct=N;
 87     for(i=1;i<=M;i++){
 88         int a=getf(eg[i].a),b=getf(eg[i].b);
 89         if(a==b) continue;
 90         fa[a]=fa[b]=++pct;h[pct]=eg[i].l;
 91         tf[a][0]=tf[b][0]=pct;
 92         ch[pct][0]=a,ch[pct][1]=b;
 93     }
 94     for(i=pct;i;i--){
 95         if(!dfn[i][0]) dfs(i);
 96     }
 97     for(i=1;i<=Q;i++){
 98         int a=rd(),b=rd(),c=rd();
 99         int x=find(a,b);
100         int pr=root[dfn[x][0]-1],no=root[dfn[x][1]];
101         int w=ztr[no]-ztr[pr];
102         if(w<c) printf("-1
");
103         else{
104             printf("%d
",source[query(pr,no,1,L,w-c+1)]);
105         }
106     }
107     return 0;
108 }
原文地址:https://www.cnblogs.com/Ressed/p/9681620.html