zoukankan      html  css  js  c++  java
  • [Kruskal重构树][主席树] Luogu P4197 Peaks

    给一个 N 个点的无向图,每个点有一个高度,每条边有一个困难度。

    多次询问求从 Vi 出发,只经过困难度小于等于 Xi 的边所能到达的点中第 K 高的点。

    Kruskal 重构树真是个好东西,既好写又好用。

    这道题把树建出来后就变成了求某个点的叶子结点中第 K 大的点。

    上面说的某个点就是 V在树中向上跳能跳到的点权 <= Xi 的点,

    这个东西显然可以用倍增来求。

    因为是求第 K 大,所以还要套一个主席树。

     1 #include<bits/stdc++.h>
     2 #define rep(i,a,b) for(register int i=a;i<=b;++i)
     3 #define rpd(i,a,b) for(register int i=a;i>=b;--i)
     4 #define rep1(i,x) for(register int i=head[x];i;i=nxt[i])
     5 typedef long long ll;
     6 const int N=5e5+5,M=5e5+5;
     7 using namespace std;
     8 inline int read(){
     9     int x=0,f=1;char ch=getchar();
    10     while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    11     while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}
    12     return x*f;
    13 }
    14 struct edge{int x,y,z;}e[M];
    15 bool cmp(edge i,edge j){return i.z<j.z;}
    16 int n,m,Q,tot,cnt,sum,rt;
    17 int H[N],bing[N<<1],head[N<<1],to[N<<1],nxt[N<<1],w[N<<1],h[N],Ls[N],Rs[N];
    18 void add(int u,int v){nxt[++tot]=head[u];head[u]=tot;to[tot]=v;}
    19 int get(int x){return bing[x]==x?x:bing[x]=get(bing[x]);}
    20 void buildkt(){
    21     rep(i,1,n<<1)bing[i]=i;
    22     sort(e+1,e+m+1,cmp);cnt=n;
    23     rep(i,1,m){
    24         int x=get(e[i].x),y=get(e[i].y),z=e[i].z;
    25         if(x==y)continue;
    26         w[++cnt]=z;add(cnt,x);add(cnt,y);
    27         bing[x]=bing[y]=cnt;
    28         if(cnt==(n<<1)-1)break;
    29     }
    30 }
    31 int f[N][25],hs[N],id[N];
    32 void dfs(int x,int fa){
    33     f[x][0]=fa;Ls[x]=n+1;Rs[x]=0;
    34     if(x<=n){h[++sum]=H[x];Ls[x]=Rs[x]=sum;return;}
    35     rep1(i,x){
    36         int p=to[i];dfs(p,x);
    37         Ls[x]=min(Ls[x],Ls[p]);
    38         Rs[x]=max(Rs[x],Rs[p]);
    39     }
    40 }
    41 void init(){rep(j,1,17)rep(i,1,(n<<1)-1)f[i][j]=f[f[i][j-1]][j-1];}
    42 int work(int start,int dis){rpd(i,17,0){int k=f[start][i];if(k==0||w[k]>dis)continue;start=k;}return start;}
    43 struct Tree{int x,l,r;}t[N<<5];int ban[N];
    44 void up(int k){t[k].x=t[t[k].l].x+t[t[k].r].x;}
    45 void build(int &k,int l,int r){k=++rt;if(l==r)return;int mid=l+r>>1;build(t[k].l,l,mid);build(t[k].r,mid+1,r);}
    46 void change(int k,int &k1,int l,int r,int p){
    47     k1=++rt;t[k1]=t[k];if(l==r){t[k1].x+=1;return;}
    48     int mid=l+r>>1;
    49     if(mid>=p)change(t[k].l,t[k1].l,l,mid,p);
    50     else change(t[k].r,t[k1].r,mid+1,r,p);
    51     up(k1);
    52 }
    53 int find(int k,int k1,int l,int r,int p){
    54     if(l==r)return hs[l];
    55     int mid=l+r>>1,opt=t[t[k1].r].x-t[t[k].r].x;
    56     if(opt>=p)return find(t[k].r,t[k1].r,mid+1,r,p);
    57     return find(t[k].l,t[k1].l,l,mid,p-opt);
    58 }
    59 int main(){
    60     n=read();m=read();Q=read();
    61     rep(i,1,n)H[i]=read();
    62     rep(i,1,m)e[i].x=read(),e[i].y=read(),e[i].z=read();
    63     buildkt();dfs((n<<1)-1,0);init();
    64     rep(i,1,n)hs[i]=h[i];sort(hs+1,hs+n+1);
    65     rep(i,1,n)id[i]=lower_bound(hs+1,hs+n+1,h[i])-hs;
    66     build(ban[0],1,n);
    67     rep(i,1,n)change(ban[i-1],ban[i],1,n,id[i]);
    68     //rep(i,1,n)cout<<i<<' '<<h[i]<<endl;
    69     while(Q--){
    70         int v=read(),x=read(),k=read(),root=work(v,x),L=Ls[root],R=Rs[root];
    71         //cout<<L<<' '<<R<<endl;
    72         if(k>R-L+1){puts("-1");continue;}
    73         printf("%d
    ",find(ban[L-1],ban[R],1,n,k));
    74     }
    75     //system("pause");
    76     return 0;
    77 }
    View Code
  • 相关阅读:
    Struts2学习笔记(四) Action(中)
    Struts2学习笔记(十) OGNL
    asp.net连接Access数据库。一般都怎么连有几种连法
    网络跃迁——C/S到B/S的“惊世一跃”
    用ASP打开远端MDB文件的方法
    solution to DreamweaverCtrls.dll
    for debugging on site,the web.config should be edited as follows
    For web.config setting,reference the book of
    1. need mssql connection method for dotnet vhost,etc
    蔡学镛推荐的编程语言REBOL编程初体验
  • 原文地址:https://www.cnblogs.com/maximumhanyu/p/11427597.html
Copyright © 2011-2022 走看看