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为根,每个点有一种颜色.我们称一种颜色占领了一个子树当且仅当没有其他颜色在这 ...
随机推荐
- java Html 转 PDF
Html 转 PDF 使用 flying-saucer 插件来完成 导入flying-saucer依赖 <dependency> <groupId>org.xhtmlrende ...
- 【JavaScript 从零开始】 数字 文本 包装对象
JavaScript中的算术运算 JavaScript 还自称更加复杂的算术运算,这些复杂的运算通过作为Math对象的属性定义的函数和常量来实现: Math.pow(2,53) //=>9007 ...
- vps服务器搭建——Linode VPS 20美元优惠获取教程
转载:http://www.cuishifeng.cn/linode/index.html?v=2 声明:本文旨在教大家怎么获得linode 20美元优惠,并免费使用4个月vps,请低调薅羊毛!(多张 ...
- [WPF]记一个Win8"缩放级别"设置导致的问题
这是我电脑的分辨率设置: 关键在于设置了缩放级别"较大",即150%的缩放. 接下来在WinForm中用各种方法取得的屏幕分辨率都是缩放之后的,但是这个时候的鼠标事件中鼠标位置也是 ...
- Linux 文件缓存 (一)
缓存印象 缓存给人的感觉就是可以提高程序运行速度,比如在桌面环境中,第一次打开一个大型程序可能需要10秒,但是关闭程序后再次打开可能只需5秒了.这是因为运行程序需要的代码.数据文件在操作系统中得到了缓 ...
- 在GDI+中如何实现以左下角为原点的笛卡尔坐标系
今天写了一个求点集合的凸包的一个算法,虽然结果求解出来了,但是想将过程用GDI+绘制出来,就需要将点绘制出来,然而c#GDI+中绘图的坐标与我们常用数学中笛卡尔坐标系是不一样的,所以就要转换GDI+中 ...
- 【代码笔记】iOS-iOS图片的原生(Graphics)
一,效果图. 二,工程图. 三,代码. RootViewController.h #import <UIKit/UIKit.h> @interface RootViewController ...
- [移动端WEB] 移动端网站响应式布局之"rem",CSS3 rem使用方式
(function(doc, win) { var docEl = doc.documentElement, resizeEvt = 'orientationchange' in window ? ' ...
- 转:导出csv文件数字会自动变科学计数法的解决方法
导出csv文件数字会自动变科学计数法的解决方法 其实这个问题跟用什么语言导出csv文件没有关系.Excel显示数字时,如果数字大于12位,它会自动转化为科学计数法:如果数字大于15位,它不仅用于科 ...
- JavaWEB SSH文件上传
一.提交表单的<form> method属性必须为post 并且添加enctype="multipart/form-data" 属性 前台: <td>上传 ...