zoukankan      html  css  js  c++  java
  • Codeforces570D Tree Requests

    dsu on tree

    题目链接

    点我跳转

    题目大意

    给定一个以(1)为根的n个节点的树,每个点上有一个字母((a-z))

    每个点的深度定义为该节点到1号节点路径上的点数.

    每次询问 (a,b), 查询以 (a) 为根的子树内深度为 (b) 的节点上的字母重新排列之后是否能构成回文串.

    解题思路

    重排之后能否构成回文串,即判断出现次数为奇数的字符个数是否小于等于1

    因为要多次询问以某个点为根深度为 (b) 的节点上的字母

    所以可以对每个节点开个 (vector) ,再把和它有关的询问保存在(vector)

    然后在 (dsu) (on) (tree) 的过程进行到该节点时遍历这个节点的 (vector) (相关询问)

    再对询问做判断→得到答案→保存答案

    最后将保存的答案按照读入的顺序排个序输出即可

    AC_Code

    #include<bits/stdc++.h>
    #define rep(i , a , b) for(int i = a ; i <= b ; i ++)
    #define int long long
    #define pb push_back
    #define fi first
    #define se second
    using namespace std;
    const int N = 5e5 + 10;
    struct Edge
    {
    	int nex , to;
    } edge[N << 2];
    int head[N] , TOT;
    void add_edge(int u , int v)
    {
    	edge[++ TOT].nex = head[u];
    	edge[TOT].to = v;
    	head[u] = TOT;
    }
    int cnt[N][26] , hson[N] , sz[N] , HH;
    int n , m , col[N] , vis[N];
    vector<pair<int ,int>>Q[N] , ans;
    void dfs(int u , int far)
    {
    	for(int i = head[u] ; i ; i = edge[i].nex)
    	{
    		int v = edge[i].to;
    		if(v == far) continue ;
    		dfs(v , u);
    		sz[u] += sz[v];
    		if(sz[v] > sz[hson[u]]) hson[u] = v;
    	}
    	sz[u] ++;
    }
    void calc(int u , int far , int val , int dep)
    {
    	cnt[dep][col[u]] += val;
    	for(int i = head[u] ; i ; i = edge[i].nex)
    	{
    		int v = edge[i].to;
    		if(v == far || v == HH) continue ;
    		calc(v , u , val , dep + 1);
    	}
    }
    void dsu(int u , int far , int op , int dep)
    {
    	for(int i = head[u] ; i ; i = edge[i].nex)
    	{
    		int v = edge[i].to;
    		if(v == hson[u] || v == far) continue ;
    		dsu(v , u , 0 , dep + 1);
    	}
    	if(hson[u]) dsu(hson[u] , u , 1 , dep + 1) , HH = hson[u];
    	calc(u , far , 1 , dep);
    	for(auto i : Q[u])
    	{
    		int b = i.fi , id = i.se , res = 0;
    		rep(j , 0 , 25)
    		{
    			if(cnt[b][j] & 1) res ++ ;
    		}
    		if(res > 1) ans.pb(make_pair(id , 0));
    		else ans.pb(make_pair(id , 1));
    	}
    	HH = 0;
    	if(!op) calc(u , far , -1 , dep);
    }
    signed main()
    {
    	cin >> n >> m;
    	rep(i , 2 , n)
    	{
    		int v;
    		cin >> v;
    		add_edge(i , v) , add_edge(v , i);
    	}
    	rep(i , 1 , n)
    	{
    		char ch;
    		cin >> ch;
    		col[i] = ch - 'a';
    	}
    	rep(i , 1 , m)
    	{
    		int a , b;
    		cin >> a >> b;
    		Q[a].pb(make_pair(b , i));
    	}
    	dfs(1 , 0);
    	dsu(1 , 0 , 0 , 1);
    	sort(ans.begin() , ans.end());
    	for(auto i : ans) 
    		if(i.se) cout << "Yes
    " ; 
    		else cout << "No
    ";
    	return 0;
    }
    
  • 相关阅读:
    面向对象-继承
    antd pro2.0 使用记录一:登录/注册/底部版权等设置
    vscode中git的配置
    电脑桌面文件夹出现在屏幕之外了,怎么解决
    百度网盘不限速-Motrix
    u盘在电脑读不出来,但别的可以读
    win10 命令重置 管理员密码
    nginx 配置
    react 记录:运行npm run eject命令暴露配置文件都报这个错误
    浏览器 连不上网 (3):DNS 服务器问题
  • 原文地址:https://www.cnblogs.com/StarRoadTang/p/14028239.html
Copyright © 2011-2022 走看看