zoukankan      html  css  js  c++  java
  • CF1062E Company

    CF1062E Company

    链接

    cf
    luogu

    题目大意

    给定一颗树,有若干个询问,每个询问给出 l,r,要求编号为 ll~rr 的点任意删去一个之后剩余点的 LCA 深度最大,输出删去点的编号和 LCA 的最大深度

    思路

    一堆点的lca就是dfs序列的最大和最小的lca
    因为只能删除一个点,那就看看删除最大的优秀还是删除最小的优秀。
    修改其他的lca是不变的。查询次大线段树麻烦,主席树还能短一点。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    const int N=1e5+7;
    int read() {
    	int x=0,f=1;char s=getchar();
    	for(;s>'9'||s<'0';s=getchar()) if(s=='-') f=-1;
    	for(;s>='0'&&s<='9';s=getchar()) x=x*10+s-'0';
    	return x*f;
    }
    int n,q,a[N];
    vector<int> G[N];
    namespace seg {
    	struct node {
    		int ls,rs,siz,nb;
    	}e[N*30];
    	int cnt,rt[N];
    	void insert(int &rt,int old,int l,int r,int id,int nb) {
    		rt=++cnt;
    		e[rt]=e[old];
    		e[rt].siz++;
    		if(l==r) return e[rt].nb=nb,void();
    		int mid=(l+r)>>1;
    		if(id<=mid) insert(e[rt].ls,e[old].ls,l,mid,id,nb);
    		else insert(e[rt].rs,e[old].rs,mid+1,r,id,nb);		
    	}
    	int k_th(int rt,int old,int l,int r,int k) {
    		if(l==r) return e[rt].nb;
    		int now=e[e[rt].ls].siz-e[e[old].ls].siz;
    		int mid=(l+r)>>1;
    		if(now>=k) return k_th(e[rt].ls,e[old].ls,l,mid,k);
    		else return k_th(e[rt].rs,e[old].rs,mid+1,r,k-now);
    	}
    }
    namespace diss_tree {
    	int dep[N],siz[N],fa[N];
    	int top[N],son[N],cnt;
    	void dfs1(int u,int f) {
            a[u]=++cnt;
    		fa[u]=f;
    		siz[u]=1;
    		for(auto v:G[u]) {
    			if(f==v) continue;
                dep[v]=dep[u]+1;
    			dfs1(v,u);
    			siz[u]+=siz[v];
    			if(siz[son[u]]<siz[v]) son[u]=v;
    		}
    	}
    	void dfs2(int u,int topf) {
    		top[u]=topf;
    		if(!son[u]) return;
    		dfs2(son[u],topf);
    		for(auto v:G[u])
    			if(!top[v]) dfs2(v,v);
    	}
    	int lca(int x,int y) {
    		while(top[x]!=top[y]) {
    			if(dep[top[x]]<dep[top[y]]) swap(x,y);
    			x=fa[top[x]];
    		}
    		return dep[x]<dep[y] ? x : y;
    	}
    }
    int main() {
    	n=read(),q=read();
    	for(int i=2;i<=n;++i) {
    		int x=read();
    		G[x].push_back(i);
    		G[i].push_back(x);
    	}
    	diss_tree::dfs1(1,0);
    	diss_tree::dfs2(1,1);
    	for(int i=1;i<=n;++i) seg::insert(seg::rt[i],seg::rt[i-1],1,n,a[i],i);
    	for(int i=1;i<=q;++i) {
    		int x=read(),y=read();
    		int first_max=seg::k_th(seg::rt[y],seg::rt[x-1],1,n,1);
    		int second_max=seg::k_th(seg::rt[y],seg::rt[x-1],1,n,2);
    		int first_min=seg::k_th(seg::rt[y],seg::rt[x-1],1,n,y-x+1);
    		int second_min=seg::k_th(seg::rt[y],seg::rt[x-1],1,n,y-x);
    		int tmp_x=diss_tree::dep[diss_tree::lca(first_max,second_min)];
    		int tmp_y=diss_tree::dep[diss_tree::lca(second_max,first_min)];
    		if(tmp_x > tmp_y) printf("%d %d
    ",first_min,tmp_x);
    		else printf("%d %d
    ",first_max,tmp_y);
    	}
    	return 0;
    }
    
    
  • 相关阅读:
    Pycharm中直接安装第三方库
    http协议与https协议
    调用第三方支付--支付宝
    探索性测试 之 极速测试
    常见HTTP状态码
    git: windows git ssh keys生成
    Jmeter实现MD5加密
    算法 ----- 排序NB二人组 堆排序 归并排序
    web 应用 及 补充
    Python Django框架 补充
  • 原文地址:https://www.cnblogs.com/dsrdsr/p/10785822.html
Copyright © 2011-2022 走看看