• Luogu4197 Peaks


    挺有意思的一个题

    Description

    link

    有一个无向图,点有点权,边有边权

    询问每个点出发经过边权不超过定值的第 (k) 大点权

    (n le 10^5 m le 5 imes 10^5)

    Solution

    我们离线所有操作之后按照边的长度排序,之后线段树合并的基操就完事了

    前半句想到了这题就没意思了

    Code

    #include<bits/stdc++.h>
    using namespace std;
    namespace yspm{
    	inline int read()
    	{
    		int res=0,f=1; char k;
    		while(!isdigit(k=getchar())) if(k=='-') f=-1;
    		while(isdigit(k)) res=res*10+k-'0',k=getchar();
    		return res*f;
    	}
    	const int N=2e6+10,M=1e5+10;
    	struct node{
    		int u,v,w,opt,id;
    		bool operator<(const node &a) const{return w==a.w?opt<a.opt:w<a.w;}
    	}s[N];
    	#define fr(p) s[p].u
    	struct tree{
    		int ls,rs,sum;
    		#define sum(p) t[p].sum
    		#define ls(p) t[p].ls
    		#define rs(p) t[p].rs
    	}t[N<<2];
    	int n,m,q,h[M],b[M],tot,cnt,fa[N],rt[N],ans[M*5];
    	inline int find(int x){return x==fa[x]?x:fa[x]=find(fa[x]);}
    	inline void push_up(int p){return sum(p)=sum(ls(p))+sum(rs(p)),void();}
    	inline void update(int &p,int l,int r,int x)
    	{
    		if(!p) p=++tot; if(l==r) return sum(p)++,void();
    		int mid=(l+r)>>1;
    		if(x<=mid) update(ls(p),l,mid,x); else update(rs(p),mid+1,r,x);
    		return push_up(p);
    	}
    	inline int merge(int x,int y,int l,int r)
    	{
    		if(!x||!y) return x+y;
    		if(l==r) return sum(x)+=sum(y),x;
    		int mid=(l+r)>>1,p=++tot;
    		ls(p)=merge(ls(x),ls(y),l,mid); rs(p)=merge(rs(x),rs(y),mid+1,r);
    		return push_up(p),p;
    	}
    	inline int query(int p,int l,int r,int k)
    	{
    		if(l==r) return l;
    		int mid=(l+r)>>1,tmp=sum(rs(p));
    		if(tmp>=k) return query(rs(p),mid+1,r,k); 
    		else return query(ls(p),l,mid,k-tmp);
    	}
    	signed main()
    	{
    		n=read(); m=read(); q=read();
    		for(int i=1;i<=n;++i)
    		{
    			h[i]=read(); b[++cnt]=h[i];
    		}
    		sort(b+1,b+cnt+1); 
    		cnt=unique(b+1,b+cnt+1)-b-1; 
    		for(int i=1;i<=n;++i) 
    		{
    			h[i]=lower_bound(b+1,b+cnt+1,h[i])-b;
    			update(rt[i],1,cnt,h[i]);
    			fa[i]=i;
    		}
    		for(int i=1;i<=m;++i)
    		{
    			s[i].u=read(); s[i].v=read(); s[i].w=read(); s[i].opt=0;
    		}
    		for(int i=1;i<=q;++i) s[i+m].id=i,s[i+m].u=read(),s[i+m].w=read(),s[i+m].v=read(),s[i+m].opt=1;
    		sort(s+1,s+m+q+1);
    		for(int i=1;i<=m+q;++i) 
    		{
    			if(!s[i].opt)
    			{
    				int ax=find(s[i].u),ay=find(s[i].v);
    				if(ax==ay) continue;
    				fa[ax]=ay;
    				rt[ay]=merge(rt[ay],rt[ax],1,cnt);
    			}
    			else
    			{
    				fr(i)=find(fr(i)); 
    				if(sum(rt[fr(i)])<s[i].v) ans[s[i].id]=-1;
    				else ans[s[i].id]=b[query(rt[fr(i)],1,cnt,s[i].v)];
    			}
    		}
    		
    		for(int i=1;i<=q;++i) printf("%d
    ",ans[i]);
    		return 0;
    	}
    }
    signed main(){return yspm::main();}
    

    Riview

    在在线处理问题的时候可以考虑离线之后这个题有啥性质

    尤其是排序有大小关系的那种,最近没少做离线排序题

  • 相关阅读:
    windows下基于IIS配置ssl证书
    IIS HTTP重定向到HTTPS
    C#:调用存储过程方法
    IIS无法启动解决方案
    C#工具:ASP.net 调用MySQL 帮助类(包括存储过程调用)
    C#工具:ASP.net 调用SQLserver帮助类
    HTTPClick调用WebApi帮助类
    三元运算符判断三种状态
    pandas模块
    numpy模块
  • 原文地址:https://www.cnblogs.com/yspm/p/12721251.html
Copyright © 2020-2023  润新知