codeforces 741D Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths

题意

给出一棵树,每条边上有一个字符,字符集大小只有22。

对于每一个子树,询问其中最长的,满足:路径上的字符集可以重组成字符串的路径的长度。

题解

明显是用mask维护信息,然后启发式合并一下。

一般启发式合并需要用map维护信息,这样的复杂度是log^2的。如果保留每个点重儿子的信息,就可以用全局变量维护,全局变量的大小就可以开很大,可以做到log。

代码

#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define rep(i, a, b) for(int i=(a); i<(b); i++)
#define sz(a) (int)a.size()
#define de(a) cout << #a << " = " << a << endl
#define dd(a) cout << #a << " = " << a << " "
#define all(a) a.begin(), a.end()
#define endl "\n"
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;
//--- const int N = 505050; int n;
int ans[N], s[N], par[N], dep[N], wson[N], sz[N], mask[22], len[1<<22];
vi g[N];
vector<pii> info[N]; inline void join(vector<pii> &a, vector<pii> &b, const int &t, const int &c, int &ans) {
if(t) swap(a, b);
for(auto u : b) {
if(~len[u.fi]) ans = max(ans, len[u.fi] + u.se - c);
rep(i, 0, 22) if(~len[u.fi ^ mask[i]]) {
ans = max(ans, len[u.fi ^ mask[i]] + u.se - c);
}
}
for(auto u : b) {
len[u.fi] = max(len[u.fi], u.se);
}
a.insert(a.end(), all(b));
} void dfs(int u, bool isw) {
info[u].pb(mp(s[u], dep[u]));
if(sz(g[u])) {
for(auto v : g[u]) if(v != wson[u]) {
dfs(v, 0);
ans[u] = max(ans[u], ans[v]);
}
dfs(wson[u], 1);
ans[u] = max(ans[u], ans[wson[u]]);
join(info[u], info[wson[u]], 1, dep[u] * 2, ans[u]);
for(auto v : g[u]) if(v != wson[u]) {
join(info[u], info[v], 0, dep[u] * 2, ans[u]);
}
if(!isw) for(auto t : info[u]) len[t.fi] = -1;
} else {
if(isw) len[s[u]] = max(len[s[u]], dep[u]);
}
} int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(0);
rep(i, 0, 22) mask[i] = (1 << i);
cin >> n;
rep(i, 2, n+1) {
string t;
cin >> par[i] >> t;
int c = t[0] - 'a';
g[par[i]].pb(i);
s[i] = s[par[i]] ^ mask[c];
dep[i] = dep[par[i]] + 1;
}
for(int i = n; i; --i) {
sz[par[i]] += ++sz[i];
if(sz[wson[par[i]]] < sz[i]) wson[par[i]] = i;
}
memset(len, -1, sizeof(len));
dfs(1, 1);
rep(i, 1, n+1) cout << ans[i] << " ";
cout << endl;
return 0;
}

codeforces 741D Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths(启发式合并)的更多相关文章

  1. codeforces 741D Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths

    题目链接:Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths 第一次写\(dsu\ on\ tree\),来记录一下 \(dsu\ o ...

  2. Codeforces 741D Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths(dsu on tree)

    感觉dsu on tree一定程度上还是与点分类似的.考虑求出跨过每个点的最长满足要求的路径,再对子树内取max即可. 重排后可以变成回文串相当于出现奇数次的字母不超过1个.考虑dsu on tree ...

  3. Codeforces.741D.Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths(dsu on tree 思路)

    题目链接 \(Description\) 给定一棵树,每条边上有一个字符(a~v).对每个节点,求它的子树中一条最长的路径,满足 路径上所有边上的字符可以重新排列成一个回文串.输出其最长长度. \(n ...

  4. CF 741D. Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths [dsu on tree 类似点分治]

    D. Arpa's letter-marked tree and Mehrdad's Dokhtar-kosh paths CF741D 题意: 一棵有根树,边上有字母a~v,求每个子树中最长的边,满 ...

  5. Codeforces 741 D - Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths

    D - Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths 思路: 树上启发式合并 从根节点出发到每个位置的每个字符的奇偶性记为每个位 ...

  6. CF 741 D. Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths

    D. Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths http://codeforces.com/problemset/probl ...

  7. codeforces 1065F Up and Down the Tree

    题目链接:codeforces 1065F Up and Down the Tree 题意:给出一棵树的节点数\(n\)以及一次移动的最大距离\(k\),现在有一个标记在根节点1处,每一次可以进行一下 ...

  8. CF741D Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths

    CF741D Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths 好像这个题只能Dsu On Tree? 有根树点分治 统计子树过x的 ...

  9. Codeforces 600E. Lomsat gelral(Dsu on tree学习)

    题目链接:http://codeforces.com/problemset/problem/600/E n个点的有根树,以1为根,每个点有一种颜色.我们称一种颜色占领了一个子树当且仅当没有其他颜色在这 ...

随机推荐

  1. FineUI表格、窗体、按钮组及事件

    //表格 @(F.Grid().IsFluid(true).CssClass("blockpanel").Title("表格").ShowHeader(true ...

  2. web前端开发教程系列-3 - 前端开发调试工具分享

    前言 一. Bug出现的原因 1. 主观原因或者是出现这么多浏览器的原因 2. 另外客观原因: 二. 调试工具 1. Firebug 2. Chrome 3. IE11 4. IETester 5. ...

  3. 数组的strong copy理解

      一.数组的不同情况下的copy,mutablecopy分析 1.不可变数组的copy(没有创建新对象,复制的只是指针)       2.不可变数组的mutable copy(创建新对象)     ...

  4. Java多态-如何理解父类引用指向子类对象

    java多态,如何理解父类引用指向子类对象 要理解多态性,首先要知道什么是“向上转型”. 我定义了一个子类Cat,它继承了Animal类,那么后者就是前者是父类.我可以通过   Cat c = new ...

  5. Java代理(二)

    前面说到了java的静态代理,这次来看看动态代理. 假设有如下接口和实现方法: package proxy; public interface Subject { public void reques ...

  6. 计算机网络:自顶向下方法(第七版)Wireshark实验指南

    这本书的每一章后面都提供了一个Wireshark实验,通过使用Wireshark抓包并手动对包进行分析可以帮助我们更好地理解各种协议和相关知识.然而,这个资源在网上好像很难找,我历经千辛万苦找到之后, ...

  7. Java数据结构基础知识你知道多少?

    http://www.cnblogs.com/qlky/p/7359462.html http://www.importnew.com/28263.html HashMap( java 7) 构造函数 ...

  8. js 实现复制到粘贴板功能

    前言:js 或者 jquery 都可以实现的复制到粘贴板功能,有时还想要有换行等格式(同 textarea) 网站地址:我的个人vue+element ui demo网站 github地址:yuleG ...

  9. Linux 调试: systemtap

    安装与配置 在ubuntu下直接用apt-get install之后不能正常使用,提示缺少调试信息或者编译探测代码时有问题. 1. 采用官网上的解决方法 2. 可以自己重新编译一次内核,然后再手工编译 ...

  10. python学习之老男孩python全栈第九期_数据库day004 -- 作业

    https://www.cnblogs.com/YD2018/p/9451809.html 11. 查询学过“001”并且也学过编号“002”课程的同学的学号.姓名 select student.si ...