codeforces 741D Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths(启发式合并)
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(启发式合并)的更多相关文章
- 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 ...
- Codeforces 741D Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths(dsu on tree)
感觉dsu on tree一定程度上还是与点分类似的.考虑求出跨过每个点的最长满足要求的路径,再对子树内取max即可. 重排后可以变成回文串相当于出现奇数次的字母不超过1个.考虑dsu on tree ...
- Codeforces.741D.Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths(dsu on tree 思路)
题目链接 \(Description\) 给定一棵树,每条边上有一个字符(a~v).对每个节点,求它的子树中一条最长的路径,满足 路径上所有边上的字符可以重新排列成一个回文串.输出其最长长度. \(n ...
- 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,求每个子树中最长的边,满 ...
- 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 思路: 树上启发式合并 从根节点出发到每个位置的每个字符的奇偶性记为每个位 ...
- 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 ...
- codeforces 1065F Up and Down the Tree
题目链接:codeforces 1065F Up and Down the Tree 题意:给出一棵树的节点数\(n\)以及一次移动的最大距离\(k\),现在有一个标记在根节点1处,每一次可以进行一下 ...
- 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的 ...
- Codeforces 600E. Lomsat gelral(Dsu on tree学习)
题目链接:http://codeforces.com/problemset/problem/600/E n个点的有根树,以1为根,每个点有一种颜色.我们称一种颜色占领了一个子树当且仅当没有其他颜色在这 ...
随机推荐
- Linux 目录流管理
目录 1. 打开/关闭文件 1). 打开目录 / opendir 2). 关闭文件 / fclose 2. 读/写目录流 1). 目录流-读 / readdir & readdir_r 3. ...
- [日常] json_encode对中文和引号的处理差异研究
json_encode()1.默认就是把所有 ASCII 可显示字符以外的统统转义为 Unicode如果把那些字符转义为 Unicode 之后,无论文件编码是否一致,都不会出现乱码,因此中文转成Uni ...
- [C语言] 数据结构-逻辑结构和物理结构
数据结构:相互之间存在一种或多种特定关系的数据元素的集合 1.数据结构分为逻辑结构和物理结构 集合结构:集合结构中的数据元素除了同属于一个集合外,他们之间没有其他关系 线性结构:线性结构中的数据元素之 ...
- 常见排序算法总结 -- java实现
常见排序算法总结 -- java实现 排序算法可以分为两大类: 非线性时间比较类排序:通过比较来决定元素间的相对次序,由于其时间复杂度不能突破O(nlogn),因此称为非线性时间比较类排序. 线性时间 ...
- 撩课-Java每天5道面试题第24天
151.springMVC和struts2的区别有哪些? .springmvc的入口是一个servlet即前端控制器(DispatchServlet), 而struts2入口是一个filter过虑器( ...
- java计算机二级笔记
java.applet.AppletAppletHTMLAppletextends Appletextends AppletprintinitcalendarCalendarCalendar 日历类J ...
- 悟空模式-java-工厂方法模式
[却说那七衣仙女自受了大圣的定身法术,一周天方能解脱,各提花篮,回奏王母说道:“齐天大圣使术法困住我等,故此来迟.”王母问道:“汝等摘了多少蟠桃?”仙女道:“只有两篮小桃,三篮中桃.至后面,大桃半个也 ...
- [js常用]百度将文字转化为语音实例
嗷嗷方便的文字转语音,不过用的时候记得到百度语音上申请key,免费的.之前在网络上看到有人写了一部分,自己丰富下,以后用也方便 <!DOCTYPE html PUBLIC "-//W3 ...
- 无效的列类型:getTimestamp not implemented for class oracle.jdbc.driver.T4CNumberAccessor
错误信息: 无效的列类型:getTimestamp not implemented for class oracle.jdbc.driver.T4CNumberAccessor 错误原因:经过排查发现 ...
- 慕课网 深入浅出javascript 笔记
javascript 数据类型 5种简单数据类型:Number.String.Boolean.Undefined.Null 1种复杂数据类型:Object = 表示赋值: == 表示比较,但是 ...