• BZOJ.3545.[ONTAK2010]Peaks(线段树合并)


    题目链接

    (Description)

    有n个座山,其高度为hi。有m条带权双向边连接某些山。多次询问,每次询问从v出发 只经过边权<=x的边 所能到达的山中,第K高的是多少。

    (Solution)

    x的限制将图分成了若干连通块,如果x单调递增的话,只需要合并连通块就可以了。
    离线,并查集维护所属连通块,线段树合并状态、查询K大。(强制在线的话可以主席树?BZOJ3551 不想写了还是写了,还好)

    强制在线的Kruskal+主席树做法:BZOJ3551

    //39360kb	5248ms
    #include <cstdio>
    #include <cctype>
    #include <algorithm>
    //#define gc() getchar()
    #define MAXIN 250000
    #define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
    const int N=1e5+5,M=5e5+5;
    
    int n,m,Q,cnt,ref[N],h[N],Ans[M],fa[N],root[N];
    char IN[MAXIN],*SS=IN,*TT=IN;
    inline int read();
    struct Edge{
    	int fr,to,val;
    	inline void Read(){
    		fr=read(), to=read(), val=read();
    	}
    	bool operator <(const Edge &a)const{
    		return val<a.val;
    	}
    }e[M];
    struct QUERY{
    	int fr,x,k,id;
    	inline void Read(int i){
    		fr=read(), x=read(), k=read(), id=i;
    	}
    	bool operator <(const QUERY &a)const{
    		return x<a.x;
    	}
    }q[M];
    struct Segment_Tree
    {
    	#define S N*18
    	#define lson son[x][0]
    	#define rson son[x][1]
    	int tot,sz[S],son[S][2];
    
    	void Insert(int &x,int l,int r,int p)
    	{
    		sz[x=++tot]=1;
    		if(l==r) return;
    		int m=l+r>>1;
    		if(p<=m) Insert(lson,l,m,p);
    		else Insert(rson,m+1,r,p);
    	}
    	int Merge(int x,int y)
    	{
    		if(!x||!y) return x^y;
    		lson=Merge(lson,son[y][0]), rson=Merge(rson,son[y][1]);
    		sz[x]+=sz[y]; /*sz[y]=0;*/ return x;
    	}
    	int Query(int x,int l,int r,int k)
    	{
    		if(l==r) return l;
    		int ls=sz[lson];
    		if(k<=ls) return Query(lson,l,l+r>>1,k);
    		return Query(rson,(l+r>>1)+1,r,k-ls);
    	}
    }T;
    
    inline int read()
    {
    	int now=0,f=1;register char c=gc();
    	for(;!isdigit(c);c=='-'&&(f=-1),c=gc());
    	for(;isdigit(c);now=now*10+c-'0',c=gc());
    	return now*f;
    }
    int Getfa(int x){
    	return x==fa[x]?x:fa[x]=Getfa(fa[x]);
    }
    inline int Find(int x)
    {
    	int l=1,r=cnt,mid;
    	while(l<r)
    		if(ref[mid=l+r>>1]<x) l=mid+1;
    		else r=mid;
    	return l;
    }
    void Merge(int x,int y)
    {
    	int r1=Getfa(x), r2=Getfa(y);
    	if(r1==r2) return;
    	fa[r2]=r1, root[r1]=T.Merge(root[r1],root[r2]);
    }
    int Query(int x,int k)
    {
    	int rt=Getfa(x);
    	return T.sz[root[rt]]<k?-1:ref[T.Query(root[rt],1,cnt,T.sz[root[rt]]-k+1)];
    }
    
    int main()
    {
    	n=read(), m=read(), Q=read();
    	for(int i=1; i<=n; ++i) ref[i]=h[i]=read(), fa[i]=i;
    	std::sort(ref+1,ref+1+n), cnt=1;
    	for(int i=2; i<=n; ++i) if(ref[i]!=ref[i-1]) ref[++cnt]=ref[i];
    	for(int i=1; i<=n; ++i) h[i]=Find(h[i]), T.Insert(root[i],1,cnt,h[i]);
    
    	for(int i=1; i<=m; ++i) e[i].Read();
    	std::sort(e+1,e+1+m);
    	for(int i=1; i<=Q; ++i) q[i].Read(i);
    	std::sort(q+1,q+1+Q);
    
    	for(int i=1,now=1; i<=Q; ++i)
    	{
    		while(now<=m && e[now].val<=q[i].x) Merge(e[now].fr,e[now].to), ++now;
    		Ans[q[i].id]=Query(q[i].fr,q[i].k);
    	}
    	for(int i=1; i<=Q; ++i) printf("%d
    ",Ans[i]);
    
    	return 0;
    }
    

    2019.11.15:

    //39404kb	5876ms 跑的又比以前慢自闭了 
    #include <cstdio>
    #include <cctype>
    #include <algorithm>
    #define gc() getchar()
    //#define MAXIN 300000
    //#define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
    typedef long long LL;
    const int N=1e5+5,M=5e5+5;
    
    int ref[N],h[N],Ans[M],root[N],fa[N];
    //char IN[MAXIN],*SS=IN,*TT=IN;
    struct Edge
    {
    	int u,v,w;
    	bool operator <(const Edge &x)const
    	{
    		return w<x.w;
    	}
    }e[M];
    struct Queries
    {
    	int s,v,k,id;
    	bool operator <(const Queries &x)const
    	{
    		return v<x.v;
    	}
    }q[M];
    struct Segment_Tree
    {
    	#define S N*18
    	#define ls son[x][0]
    	#define rs son[x][1]
    	#define lson ls,l,l+r>>1
    	#define rson rs,(l+r>>1)+1,r
    	int tot,son[S][2],sz[S];
    	#undef S
    
    	void Insert(int &x,int l,int r,int p)
    	{
    		sz[x=++tot]=1;
    		if(l<r) p<=(l+r>>1) ? Insert(lson,p) : Insert(rson,p);
    	}
    	int Merge(int x,int y)
    	{
    		if(!x||!y) return x|y;
    		ls=Merge(ls,son[y][0]), rs=Merge(rs,son[y][1]);
    		return sz[x]+=sz[y],x;
    	}
    	int Query(int x,int l,int r,int k)
    	{
    		if(l==r) return l;
    		int lsz=sz[ls];
    		return lsz>=k?Query(lson,k):Query(rson,k-lsz);
    	}
    }T;
    
    inline int read()
    {
    	int now=0;register char c=gc();
    	for(;!isdigit(c);c=gc());
    	for(;isdigit(c);now=now*10+c-48,c=gc());
    	return now;
    }
    int Getfa(int x)
    {
    	return x==fa[x]?x:fa[x]=Getfa(fa[x]);
    }
    inline int Find(int x,int r)
    {
    	int l=1,mid;
    	while(l<r)
    		if(ref[mid=l+r>>1]<x) l=mid+1;
    		else r=mid;
    	return l;
    }
    inline void Merge(int x,int y)
    {
    	int r1=Getfa(x),r2=Getfa(y);
    	if(r1!=r2) fa[r2]=r1, root[r1]=T.Merge(root[r1],root[r2]);
    }
    inline int Query(int n,int x,int k)
    {
    	int rt=root[Getfa(x)];
    	return T.sz[rt]<k?-1:ref[T.Query(rt,1,n,T.sz[rt]-k+1)];
    }
    
    int main()
    {
    	const int n=read(),m=read(),Q=read();
    	for(int i=1; i<=n; ++i) ref[i]=h[i]=read();
    	std::sort(ref+1,ref+1+n); int cnt=1;
    	for(int i=2; i<=n; ++i) if(ref[i]!=ref[i-1]) ref[++cnt]=ref[i];
    	for(int i=1; i<=n; ++i) h[i]=Find(h[i],cnt);
    	for(int i=1; i<=n; ++i) T.Insert(root[i],1,cnt,h[i]);
    
    	for(int i=1; i<=m; ++i) e[i]=(Edge){read(),read(),read()};
    	for(int i=1; i<=Q; ++i) q[i]=(Queries){read(),read(),read(),i};
    	std::sort(e+1,e+1+m), std::sort(q+1,q+1+Q);
    
    	for(int i=1; i<=n; ++i) fa[i]=i;
    	e[m+1].w=2e9;
    	for(int i=1,now=1; i<=Q; ++i)
    	{
    		while(e[now].w<=q[i].v) Merge(e[now].u,e[now].v), ++now;
    		Ans[q[i].id]=Query(cnt,q[i].s,q[i].k);
    	}
    	for(int i=1; i<=Q; printf("%d
    ",Ans[i++]));
    
    	return 0;
    }
    
  • 相关阅读:
    计算机网络基础
    OA项目(MVC项目)
    修改XML的节点内容
    项目实战-电商(网上书城)
    DataTables ajax bootstrap 分页/搜索/排序/常见问题
    DNS服务器解析域名的过程
    bootstrap 模态框
    QuickChm 制作chm文档 chm文档脚本错误,乱码
    poi 读取word文档
    commons -lang(2) RandomStringUtils RandomUtils
  • 原文地址:https://www.cnblogs.com/SovietPower/p/9303483.html
Copyright © 2020-2023  润新知