zoukankan      html  css  js  c++  java
  • #主席树,dsu on tree,树上倍增#洛谷 3302 [SDOI2013]森林

    题目


    分析

    (k)大的问题可以用主席树解决,
    下标为节点离散化后的权值,
    连边操作考虑合并两棵树,
    如果暴力合并那肯定会T飞,考虑启发式合并
    同时维护子树内的lca,方便主席树的查询


    代码

    #include <cstdio>
    #include <cctype>
    #include <algorithm>
    #define rr register
    using namespace std;
    const int N=80011; struct node{int y,next;}e[N<<1];
    int a[N],b[N],n,m,k=1,Q,fat[N],f[N][17],siz[N],dep[N],rt[N],ls[N],M;
    struct Chair{
        int w[N<<7],ls[N<<7],rs[N<<7],cnt;
        inline void build(int &rt,int l,int r){
            w[rt=++cnt]=0; rr int mid=(l+r)>>1;
            if (l<r) build(ls[rt],l,mid),build(rs[rt],mid+1,r); 
        }
        inline void update(int &rt,int l,int r,int k){
            rr int trt=++cnt,mid=(l+r)>>1;
            ls[trt]=ls[rt],rs[trt]=rs[rt],w[trt]=w[rt]+1,rt=trt;
            if (l==r) return;
            k<=mid?update(ls[trt],l,mid,k):update(rs[trt],mid+1,r,k);
        }
        inline signed query(int fi,int se,int th,int fo,int l,int r,int kth){
        	if (l==r) return b[l];
        	rr int mid=(l+r)>>1,lef=w[ls[fi]]+w[ls[se]]-w[ls[th]]-w[ls[fo]];
        	if (kth<=lef) return query(ls[fi],ls[se],ls[th],ls[fo],l,mid,kth);
        	    else query(rs[fi],rs[se],rs[th],rs[fo],mid+1,r,kth-lef);
        	
    	}
    }Tre;
    inline signed iut(){
    	rr int ans=0; rr char c=getchar();
    	while (!isdigit(c)) c=getchar();
    	while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
    	return ans;
    }
    inline void print(int ans){
    	if (ans>9) print(ans/10);
    	putchar(ans%10+48);
    }
    inline signed getf(int u){return fat[u]==u?u:fat[u]=getf(fat[u]);}
    inline void add(int x,int y){
    	e[++k]=(node){y,ls[x]},ls[x]=k;
    	e[++k]=(node){x,ls[y]},ls[y]=k;
    }
    inline void dfs(int x,int fa,int root){
    	f[x][0]=fa,dep[x]=dep[fa]+1,fat[x]=fa,++siz[root];
    	for (rr int i=1;i<=16;++i) f[x][i]=f[f[x][i-1]][i-1];
    	Tre.update(rt[x]=rt[fa],1,M,a[x]);
    	for (rr int i=ls[x];i;i=e[i].next)
    	if (e[i].y!=fa) dfs(e[i].y,x,root);
    }
    inline signed lca(int x,int y){
    	if (dep[x]<dep[y]) x^=y,y^=x,x^=y;
    	for (rr int i=16;~i;--i)
    	if (dep[f[x][i]]>=dep[y]) x=f[x][i];
        if (x==y) return x;
        for (rr int i=16;~i;--i)
        if (f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i];
        return f[x][0];
    }
    signed main(){
    	iut(),n=iut(),m=iut(),Q=iut(),Tre.cnt=0;
    	for (rr int i=1;i<=n;++i) b[i]=a[i]=iut(),fat[i]=i;
    	for (rr int i=1;i<=m;++i) add(iut(),iut());
    	sort(b+1,b+1+n),M=unique(b+1,b+1+n)-b-1,Tre.build(rt[0],1,M);
    	for (rr int i=1;i<=n;++i) a[i]=lower_bound(b+1,b+1+M,a[i])-b;
    	for (rr int i=1;i<=n;++i) if (fat[i]==i) dfs(i,0,i),fat[i]=i;
    	for (rr int lans=0;Q;--Q){
    		rr char c=getchar();
    		while (c!='Q'&&c!='L') c=getchar();
            rr int x=iut()^lans,y=iut()^lans;
            if (c=='L'){
            	rr int fa=getf(x),fb=getf(y); add(x,y);
            	if (siz[fa]<siz[fb])
    			    fa^=fb,fb^=fa,fa^=fb,
    			        x^=y,y^=x,x^=y;
    			dfs(y,x,fa);
    		}else{
    			rr int kth=iut()^lans,LCA=lca(x,y);
    			lans=Tre.query(rt[x],rt[y],rt[LCA],rt[f[LCA][0]],1,M,kth);
    			print(lans),putchar(10);
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    MSDN Magazine搞错了
    Visual Studio 2005中设置调试符号(Debug Symbols)
    BCB 6的问题
    吴裕雄天生自然Spring Boot使用Spring Data JPA实现人与身份证的一对一关系映射
    吴裕雄天生自然Spring BootSpring Data JPA
    吴裕雄天生自然Spring BootSpring Boot对JSP的支持
    吴裕雄天生自然Spring BootSpring Boot的异常统一处理
    吴裕雄天生自然Spring Boot使用Spring Data JPA实现Author与Article的一对多关系映射
    吴裕雄天生自然Spring Boot解决 Error creating bean with name 'entityManagerFactory' defined in class path resource
    吴裕雄天生自然Spring Boot@ExceptionHandler注解和@ControllerAdvice注解
  • 原文地址:https://www.cnblogs.com/Spare-No-Effort/p/13820873.html
Copyright © 2011-2022 走看看