zoukankan      html  css  js  c++  java
  • [Nowcoder] 保护

    题意:...
    思路:
    \(LCA\)乱搞+启发式合并(堆)

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn = 200010;
    const int maxm = maxn << 2;
    int n,m;
    int cnt;
    int rt[maxn];
    int head[maxn];
    int dep[maxn];
    int f[maxn][26];
    vector<int>v[maxn];
    struct edge {
    	int to;
    	int nxt;
    }e[maxn << 1];
    inline void add(int u,int v) {
    	e[++cnt].to = v;
    	e[cnt].nxt = head[u];
    	head[u] = cnt;
    	return;
    }
    struct node {
    	int l;
    	int r;
    	int sum;
    }t[maxm];
    
    inline int find_lca(int x,int y) {
    	if(dep[x] < dep[y]) swap(x,y);
    	int tmp = dep[x] - dep[y];
    	for(int i = 20;i >= 0; --i) {
    		if(tmp >> i & 1) {
    			x = f[x][i];
    		}
    	}
    	if(x == y) return x;
    	for(int i = 20; i >= 0; --i) {
    		if(f[x][i] != f[y][i]) {
    			x = f[x][i];
    			y = f[y][i];
    		}
    	}
    	return f[x][0];
    }
    //calc huan
    inline void dfs1(int u,int fa) {
    	for(int i = 1;i <= 20; ++i) {
    		f[u][i] = f[f[u][i - 1]][i - 1];
    	}
    	for(int i = head[u];i;i=e[i].nxt) {
    		int y = e[i].to;
    		if(y != fa) {
    			f[y][0] = u;
    			dep[y] = dep[u] + 1;
    			dfs1(y,u);
    		}
    	}
    }
    int tot;
    //dui
    
    inline void insert(int l,int r,int &now,int x) {
    	if(!now) {
    		now = ++tot;
    		t[now].sum ++;
    	}
    	if(l == r) return;
    	int mid = (l + r) >> 1;
    	if(x <= mid) {
    		insert(l,mid,t[now].l,x);
    	}
    	else insert(mid + 1,r,t[now].r,x);
    }
    
    //duihebing
    inline int merge(int x,int y) {
    	if(!x || !y) {
    		return x | y;
    	}
    	int now = ++tot;
    	t[now].l = merge(t[x].l,t[y].l);
    	t[now].r = merge(t[x].r,t[y].r);
    	t[now].sum = t[x].sum + t[y].sum;
    	return now;	
    }
    
    inline int query(int l,int r,int now,int x) {
    	if(l == r) return l;
    	int mid = (l + r) >> 1;
    	if(t[t[now].l].sum >= x) {
    		return query(l,mid,t[now].l,x);
    	}
    	else {
    		return query(mid + 1,r,t[now].r,x - t[t[now].l].sum);
    	}
    }
    
    inline void dfs2(int x) {
    	for(int i = 0;i < v[x].size(); ++i) {
    		insert(1,n,rt[x],v[x][i]);
    	}
    	for(int i = head[x];i;i=e[i].nxt) {
    		int y = e[i].to;
    		if(y != f[x][0]) {
    			dfs2(y);
    			rt[x] = merge(rt[x],rt[y]);
    		}
    	}
    }
    int x,y,q;
    #define pb(x) push_back(x)
    int main () {
    	scanf("%d %d",&n,&m);
    	for(int i = 1;i < n; ++i) {
    		scanf("%d %d",&x,&y);
    		add(x,y);
    		add(y,x);
    	}
    	dep[1] = 1;
    	dfs1(1,0);
    	for(int i = 1;i <= m; ++i) {
    		scanf("%d %d",&x,&y);
    		int FF = find_lca(x,y);
    		v[x].pb(dep[FF]);
    		v[y].pb(dep[FF]);
    	}
    	dfs2(1);
    	scanf("%d",&q);
    	while(q--) {
    		scanf("%d %d",&x,&y);
    		int tmp = query(1,n,rt[x],y);
    		printf("%d\n",max(dep[x] - tmp,0));
    	}
    	return 0;
    }
    
    
  • 相关阅读:
    Websphere 系列的https证书的配置说明
    Linux下运行windows程序
    Linux常见命令(三)
    使用Java语言开发微信公众平台(八)——自定义菜单功能
    Linux常见命令(二)
    微信小程序,前端大梦想(八)
    微信小程序,前端大梦想(七)
    使用Java语言开发微信公众平台(七)——音乐消息的回复
    微信小程序,前端大梦想(六)
    微信小程序,前端大梦想(五)
  • 原文地址:https://www.cnblogs.com/akoasm/p/9614684.html
Copyright © 2011-2022 走看看