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. C#神奇的扩展方法

      以前总听说扩展方法扩展方法,只是听说是C#3.0后出来的新玩意,也仅仅是知道Linq中用到好多的扩展方法,但是他究竟是个什么东东,怎么用它,用它的好处是什么,总是模模糊糊,那么我们今天就尝试揭开它 ...

  2. sql 数据库数据 批量判断修改

    A表B表相关联  更新B表中的VisitWeek字段值 CCD_PartnerVisit 此为B表 Dell_FiscalWeek  此为A表 UPDATE CCD_PartnerVisit SET ...

  3. 【原】Redis实现生成自增流水号

    场景: 公司内部有个业务场景是后台审核之后需要生成一个流水号,规则是: 201807280001,201807280002,201807280003,后面四位依次递增,前面年月日取当前时间并且转换成y ...

  4. java并发编程的艺术(四)---ConcurrentHashMap原理解析

    本文来源于翁舒航的博客,点击即可跳转原文观看!!!(被转载或者拷贝走的内容可能缺失图片.视频等原文的内容) 若网站将链接屏蔽,可直接拷贝原文链接到地址栏跳转观看,原文链接:https://www.cn ...

  5. python Django html 模板循环条件

    views里返回数据为例: renturn render(request,'xxx.html',{'obj':123,'k1':[1,2,3,4],'k2':{'name':'yooma','age' ...

  6. 【代码笔记】iOS-单击手势的添加

    一,效果图. 二,工程图. 三,代码. RootViewController.h #import <UIKit/UIKit.h> @interface RootViewController ...

  7. Django基础八之cookie和session

    一 会话跟踪 我们需要先了解一下什么是会话!可以把会话理解为客户端与服务器之间的一次会晤,在一次会晤中可能会包含多次请求和响应.例如你给10086打个电话,你就是客户端,而10086服务人员就是服务器 ...

  8. Ubuntu OpenJDK + Tomcat7 的安装

    jdk1.7.0安装首先安装openjdk,安装命令如下图. 安装好之后检查jdk文件路径,如下图. 建立链接(ls),如下图. 成功之后,配置环境变量,并重新运行一下,如下图. 环境变量在文件最后面 ...

  9. Mysql InnoDB的四个事务隔离级别和(分别逐级解决的问题)脏读,不可重复读,虚读

    MySqlInnoDB的事务隔离级别有四个:(默认是可重复读repeatable read) 未提交读 read uncommit : 在另一个事务修改了数据,但尚未提交,在本事务中SELECT语句可 ...

  10. web页面超时自动退出方法

    思路: 使用 mousemover 事件来监测是否有用户操作页面,写一个定时器间隔特定时间检测是否长时间未操作页面,如果是,退出: 具体时间代码如下(js):var lastTime = new Da ...