zoukankan      html  css  js  c++  java
  • CodeForces-1304 E 1-Trees and Queries 树上思维

    CodeForces-1304 E 1-Trees and Queries 树上思维

    题意

    给定一颗(n)个点的树,树上相邻点的距离为1.

    现有(q)个询问,每个询问包含5个整数(x,y,a,b,k)

    在原树上连上一条新的边((x,y))判断是否存在(a)(b)的长度为(k)的路径

    注意路径可以重复走点

    [3leq n leq10^5\ 1leq qleq 10^5\ k leq 10^9 ]

    分析

    先不考虑这题的特殊性,

    注意到可以重复走,仅当两点间的简单路径长度小于等于(k)且和(k)的差是偶数的时候才输出YES

    偶数是因为既然要重复走,多走的那部分贡献肯定是偶数

    那么想想新连一条边带来的影响

    好像没什么影响?使得从简单路径多拓展到了可以通过这条路径走

    所以相当于两条简单路径的叠加

    因此就是把原来的一条多了两条而已

    代码

    #include<bits/stdc++.h>
    using namespace std;
    typedef unsigned long long ull;
    typedef long long ll;
    
    ull readull(){
    	ull x = 0;
    	int f = 1;
    	char ch = getchar();
    	while(ch < '0' || ch > '9') {
    		if(ch == '-') f = -1;
    		ch = getchar(); 
    	}
    	while(ch >= '0' && ch <= '9'){
    		x = x * 10 + ch - '0';
    		ch = getchar();
    	}
    	return f * x;
    }
    int readint(){
    	int x = 0;
    	int f = 1;
    	char ch = getchar();
    	while(ch < '0' || ch > '9') {
    		if(ch == '-') f = -1;
    		ch = getchar(); 
    	}
    	while(ch >= '0' && ch <= '9'){
    		x = x * 10 + ch - '0';
    		ch = getchar();
    	}
    	return f * x;
    }
    
    const int maxn = 1e5 + 5;
    
    int fa[maxn],son[maxn],dep[maxn],siz[maxn];
    int top[maxn],pre[maxn],id[maxn];
    int tt;
    
    vector<int> e[maxn];
    
    void dfs1(int u){
    	siz[u] = 1;
    	for(auto v:e[u]){
    		if(v == fa[u]) continue;
    		dep[v] = dep[u] + 1;
    		fa[v] = u;
    		dfs1(v);
    		siz[u] += siz[v];
    		if(siz[v] > siz[son[u]]) 
    			son[u] = v;
    	}
    }
    
    void dfs2(int u,int x){
    	pre[u] = ++tt;
    	id[tt] = u;
    	top[u] = x;
    	if(!son[u]) return;
    	dfs2(son[u],x);
    	for(auto v:e[u]){
    		if(v == fa[u] || v == son[u]) continue;
    		dfs2(v,v);
    	} 
    }
    
    int lca(int x,int y){
    	while(top[x] != top[y]){
    		if(dep[top[x]] > dep[top[y]])
    			x = fa[top[x]];
    		else 
    			y = fa[top[y]];
    	}
    	return dep[x] > dep[y] ? y : x;
    }
    
    int dis(int a,int b){
    	return dep[a] + dep[b] - 2 * dep[lca(a,b)];
    }
    
    bool check(int a,int b){
    	return a <= b && (b - a) % 2 == 0;
    }
    
    int main(){
    	int n = readint();
    	for(int i = 1;i < n;i++){
    		int u = readint();
    		int v = readint();
    		e[u].push_back(v);
    		e[v].push_back(u);
    	}
    	dfs1(1);
    	dfs2(1,1);
    	int q = readint();
    	while(q--){
    		int x = readint();
    		int y = readint();
    		int a = readint();
    		int b = readint();
    		int ab = dis(a,b);
    		int xa = dis(x,a);
    		int xb = dis(x,b);
    		int ay = dis(a,y);
    		int by = dis(b,y);
    		int k = readint();
    		if(check(ab,k) || check(xa + by + 1,k) || check(xb + ay + 1,k)) puts("YES");
    		else puts("NO");
    	}
    }
    
  • 相关阅读:
    绝对布局absoluteLayout
    表格布局tabelLayout
    DP问题如何确定状态
    秒杀多线程第四篇 一个经典的多线程同步问题
    循环队列
    【Unity3d】【项目学习心得】从资源server下载资源(一)
    矩阵经典题目六:poj 3070 Fibonacci
    Mean Shift具体介绍
    Android ViewPager使用具体解释
    Android中ExpandableListView控件基本使用
  • 原文地址:https://www.cnblogs.com/hznumqf/p/13934245.html
Copyright © 2011-2022 走看看