zoukankan      html  css  js  c++  java
  • 【洛谷P3224】【HNOI2012】—永无乡(线段树合并)

    传送门

    线段树合并板子题

    线段树合并的复杂度要根据两颗树的相似度而定的

    又因为一颗线段树的值域确定了,其形状也就确定了(只要你是好好写的ll,mid,mid,rr

    这道题中每个岛的重要度都不同

    所以把所有岛构成的权值线段树一个个合并的复杂度总计也只有O(nlogn)O(nlogn)

    而两颗完全一样的线段树合并复杂度单次就有O(nlogn)O(nlogn)

    这道题合并的步骤很简单

    因为只需要查值

    一直合并sizsiz直到递归到在某一棵树的叶子节点returnreturn就可以了

    试了下启发式合并但效果不大

    好吧我个sbsb这种线段树合并和启不启发没有关系的

    观察mergemerge可以很好发现这一点

    #include<bits/stdc++.h>
    using namespace std;
    inline int read(){
    	char ch=getchar();
    	int res=0,f=1;
    	while(!isdigit(ch)){if(ch=='-')f=-f;ch=getchar();}
    	while(isdigit(ch))res=(res<<3)+(res<<1)+(ch^48),ch=getchar();
    	return res*f;
    }
    const int N=100005;
    int n,m,q,a[N],lc[N<<6],rc[N<<6],rt[N<<6],sum[N<<6],fa[N],tot,pos[N];
    char c[5];
    #define mid ((l+r)>>1)
    int find(int x){
    	return fa[x]==x?fa[x]:fa[x]=find(fa[x]);
    }
    void update(int &now,int l,int r,int k){
    	if(!now)now=++tot;
    	sum[now]++;
    	if(l==r)return;
    	if(k<=mid)update(lc[now],l,mid,k);
    	else update(rc[now],mid+1,r,k);
    }
    void merge(int &u,int v){
    	if(!u||!v){u+=v;return;}
    	sum[u]+=sum[v];
    	merge(lc[u],lc[v]);
    	merge(rc[u],rc[v]);
    }
    int query(int u,int l,int r,int k){
    	if(l==r)return l;
    	int del=sum[lc[u]];
    	if(k<=del)return query(lc[u],l,mid,k);
    	else return query(rc[u],mid+1,r,k-del);
    }
    int main(){
    	n=read(),m=read();
    	for(int i=1;i<=n;i++)a[i]=read(),pos[a[i]]=i,fa[i]=i,update(rt[i],1,n,a[i]);
    	for(int i=1;i<=m;i++){
    		int u=read(),v=read();
    		int f1=find(u),f2=find(v);
    		if(f1!=f2)fa[f1]=f2,merge(rt[f2],rt[f1]);//
    	}
    	int q=read();
    	while(q--){
    		scanf("%s",c);
    		if(c[0]=='B'){
    			int u=read(),v=read();
    			int f1=find(u),f2=find(v);
    			if(f1!=f2)fa[f1]=f2,merge(rt[f2],rt[f1]);
    		}
    		else{
    			int u=read(),k=read();
    			u=find(u);
    			if(sum[rt[u]]<k)cout<<-1<<'
    ';
    			else cout<<pos[query(rt[u],1,n,k)]<<'
    ';
    		}
    	}
    }
    
  • 相关阅读:
    分布式跑批的实现流程
    Java1.8新特性Stream流处理集合元素
    RocketMQ消息存储和查询原理(引用清幽之地 清幽之地的博客)
    Markdown使用持续更新
    一次百万请求mq堆积的生产排查
    Spring Boot打包部署修改jar文件名
    Spring Boot的应用启动器
    Spring Boot配置文件application.properties
    Eclipse中出现.classPath(拒绝访问)
    PHP文件上传的相关配置
  • 原文地址:https://www.cnblogs.com/stargazer-cyk/p/10366354.html
Copyright © 2011-2022 走看看