zoukankan      html  css  js  c++  java
  • BZOJ3545 [ONTAK2010]Peaks kruskal 并查集 主席树 dfs序

    欢迎访问~原文出处——博客园-zhouzhendong

    去博客园看该题解


    题目传送门 - BZOJ3545


    题意概括

    Description

    在Bytemountains有N座山峰,每座山峰有他的高度h_i。有些山峰之间有双向道路相连,共M条路径,每条路径有一个困难值,这个值越大表示越难走,现在有Q组询问,每组询问询问从点v开始只经过困难值小于等于x的路径所能到达的山峰中第k高的山峰,如果无解输出-1。

    Input

    第一行三个数N,M,Q。
    第二行N个数,第i个数为h_i
    接下来M行,每行3个数a b c,表示从a到b有一条困难值为c的双向路径。
    接下来Q行,每行三个数v x k,表示一组询问。

    Output

    对于每组询问,输出一个整数表示答案。


    题解

    这题卡常,要读入优化。

    代码

    #include <cstring>
    #include <cstdio>
    #include <cstdlib>
    #include <algorithm>
    #include <cmath>
    using namespace std;
    const int N=100005,M=500005,S=N*2,Inf=1e9+5;
    bool isd(char ch){
    	return '0'<=ch&&ch<='9';
    }
    void read(int &x){
    	x=0;
    	char ch=getchar();
    	while (!isd(ch))
    		ch=getchar();
    	while (isd(ch))
    		x=(x<<1)+(x<<3)+ch-48,ch=getchar();
    }
    struct Edge{
    	int x,y,z;
    	void Read(){
    		read(x),read(y),read(z);
    	}
    }e[M];
    bool cmpz(Edge a,Edge b){
    	return a.z<b.z;
    }
    struct MQset{//并查集 
    	int cnt,fa[N*2];
    	void clear(){cnt=0;}
    	int getf(int k){return fa[k]==k?k:fa[k]=getf(fa[k]);}
    	void push(int x){fa[x]=x;}
    	void merge(int x,int y){fa[getf(x)]=getf(y);}
    }s;
    int n,m,q,h[N];
    int fa[S],lc[S],rc[S],val[S],cnt;
    int anst[S][20],time,in[S],out[S],dfn[S];
    void dfs(int rt){
    	anst[rt][0]=fa[rt];
    	for (int i=1;i<20;i++)
    		anst[rt][i]=anst[anst[rt][i-1]][i-1];
    	in[rt]=time;
    	if (!lc[rt])
    		dfn[++time]=rt;
    	else
    		dfs(lc[rt]),dfs(rc[rt]);
    	out[rt]=time;
    }
    const int SIZE=N*2*20*2;
    int Ha[N],hs;
    int ls[SIZE],rs[SIZE],sum[SIZE],total,root[N];
    void LSH(){
    	int hs_=1;
    	sort(Ha+1,Ha+hs+1);
    	for (int i=2;i<=hs;i++)
    		if (Ha[i]!=Ha[i-1])
    			Ha[++hs_]=Ha[i];
    	hs=hs_;
    }
    int find(int x){
    	return lower_bound(Ha+1,Ha+hs+1,x)-Ha;
    }
    void build(int &rt,int L,int R){
    	rt=++total;
    	sum[rt]=0;
    	if (L==R)
    		return;
    	int mid=(L+R)>>1;
    	build(ls[rt],L,mid);
    	build(rs[rt],mid+1,R);
    }
    void add(int prt,int &rt,int L,int R,int pos){
    	rt=++total;
    	if (L==R){
    		sum[rt]=sum[prt]+1;
    		return;
    	}
    	int mid=(L+R)>>1;
    	if (pos<=mid)
    		add(ls[prt],ls[rt],L,mid,pos),rs[rt]=rs[prt];
    	else
    		add(rs[prt],rs[rt],mid+1,R,pos),ls[rt]=ls[prt];
    	sum[rt]=sum[ls[rt]]+sum[rs[rt]];
    }
    int query(int prt,int rt,int L,int R,int k){
    	if (L==R)
    		return Ha[L];
    	int Rz=sum[rs[rt]]-sum[rs[prt]];
    	int mid=(L+R)>>1;
    	if (Rz>=k)
    		return query(rs[prt],rs[rt],mid+1,R,k);
    	else
    		return query(ls[prt],ls[rt],L,mid,k-Rz);
    }
    int find(int x,int v){
    	for (int i=19;i>=0;i--)
    		if (val[anst[x][i]]<=v)
    			x=anst[x][i];
    	return x;
    }
    int main(){
    	read(n),read(m),read(q);
    	for (int i=1;i<=n;i++)
    		read(h[i]),Ha[i]=h[i];
    	hs=n;
    	LSH();
    	for (int i=1;i<=n;i++)
    		h[i]=find(h[i]);
    	for (int i=1;i<=m;i++)
    		e[i].Read();
    	sort(e+1,e+m+1,cmpz);
    	s.clear();
    	for (int i=1;i<=n;i++){
    		s.push(i);
    		fa[i]=lc[i]=rc[i]=val[i]=0;
    	}
    	cnt=n;
    	for (int i=1;i<=m;i++){
    		int x=e[i].x,y=e[i].y,z=e[i].z;
    		x=s.getf(x),y=s.getf(y);
    		if (x==y)
    			continue;
    		s.push(++cnt);
    		fa[x]=fa[y]=cnt;
    		fa[cnt]=0,lc[cnt]=x,rc[cnt]=y,val[cnt]=z;
    		s.fa[x]=s.fa[y]=cnt;
    	}
    	val[0]=Inf;
    	time=0;
    	dfs(cnt);
    	build(root[0],1,n);
    	for (int i=1;i<=n;i++)
    		add(root[i-1],root[i],1,n,h[dfn[i]]);
    	for (int i=1;i<=q;i++){
    		int v,x,k,y;
    		read(v),read(x),read(k);
    		y=find(v,x);
    		if (out[y]-in[y]<k)
    			puts("-1");
    		else
    			printf("%d
    ",query(root[in[y]],root[out[y]],1,n,k));
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    Flask 5 模板1
    Flask 4 拓展
    Python学习札记(二十四) 函数式编程5 返回函数
    Python学习札记(二十三) 函数式编程4 sorted
    Docker:Err http://archive.ubuntu.com trusty InRelease & E: Unable to locate package [name] 问题
    解决 docker: Error response from daemon: ... : net/http: TLS handshake timeout.
    Ubuntu 安装Docker
    Flask 3 程序的基本结构2
    Flask 2 程序的基本结构1
    Flask 1 Introductory Chapter
  • 原文地址:https://www.cnblogs.com/zhouzhendong/p/BZOJ3545.html
Copyright © 2011-2022 走看看