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

思路:

树上启发式合并

从根节点出发到每个位置的每个字符的奇偶性记为每个位置的状态,每次统计一下每个状态的最大深度

为了保证链经过当前节点u,我们先计算每个子树的答案,再更新子树状态对深度的贡献。

代码:

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize(4)
#include<bits/stdc++.h>
using namespace std;
#define y1 y11
#define fi first
#define se second
#define pi acos(-1.0)
#define LL long long
#define ls rt<<1, l, m
#define rs rt<<1|1, m+1, r
//#define mp make_pair
#define pb push_back
#define ULL unsigned LL
#define pll pair<LL, LL>
#define pli pair<LL, int>
#define pii pair<int, int>
#define piii pair<pii, int>
#define pdi pair<double, int>
#define pdd pair<double, double>
#define mem(a, b) memset(a, b, sizeof(a))
#define debug(x) cerr << #x << " = " << x << "\n";
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
//head inline int read() {
int a = , b = ;
char ch = getchar();
while(ch < '' || ch > '') {
if(ch == '-') a = -;
ch = getchar();
}
while('' <= ch && ch <= '') {
b = b* + ch-'';
ch = getchar();
}
return a*b;
}
const int N = 5e5 + , M = 5e6 + ;
const int INF = 1e8;
vector<pii> g[N];
int n, p, dp[N], sz[N], son[N], deep[N], st[N], mx[M];
char c[];
void get_son(int u, int o) {
sz[u] = ;
deep[u] = deep[o] + ;
for (int i = ; i < g[u].size(); ++i) {
int v = g[u][i].fi;
int w = g[u][i].se;
st[v] = st[u] ^ (<<w);
get_son(v, u);
if(sz[v] > sz[son[u]]) son[u] = v;
sz[u] += sz[v];
}
}
void CAL(int p, int u) {
if(mx[st[u]] >= ) dp[p] = max(dp[p], mx[st[u]]+deep[u]-*deep[p]);
for (int i = ; i < ; ++i) {
if(mx[st[u]^(<<i)] >= ) dp[p] = max(dp[p], mx[st[u]^(<<i)]+ deep[u]-*deep[p]);
}
for (int i = ; i < g[u].size(); ++i) {
int v = g[u][i].fi;
CAL(p, v);
}
}
void ADD(int u) {
mx[st[u]] = max(mx[st[u]], deep[u]);
for (int i = ; i < g[u].size(); ++i) {
int v = g[u][i].fi;
ADD(v);
}
}
void DELETE(int u) {
if(mx[st[u]] >= ) mx[st[u]] = -INF;
for (int i = ; i < g[u].size(); ++i) {
int v = g[u][i].fi;
DELETE(v);
}
}
void dfs(int u) {
for (int i = ; i < g[u].size(); ++i) {
int v = g[u][i].fi;
if(v != son[u]) {
dfs(v);
DELETE(v);
}
} if(son[u]) dfs(son[u]); if(mx[st[u]] >= ) dp[u] = mx[st[u]] - deep[u];
for (int i = ; i < ; ++i) {
if(mx[st[u]^(<<i)] >= ) dp[u] = max(dp[u], mx[st[u]^(<<i)] - deep[u]);
} mx[st[u]] = max(mx[st[u]], deep[u]);
for (int i = ; i < g[u].size(); ++i) {
int v = g[u][i].fi;
if(v != son[u]) {
CAL(u, v);
ADD(v);
}
}
for (int i = ; i < g[u].size(); ++i) {
int v = g[u][i].fi;
dp[u] = max(dp[u], dp[v]);
}
}
int main() {
n = read();
for (int i = ; i <= n; ++i) {
p = read();
scanf("%s", c);
g[p].pb({i, c[]-'a'});
}
get_son(, );
for (int i = ; i < M; ++i) mx[i] = -INF;
dfs();
for (int i = ; i <= n; ++i) printf("%d%c", dp[i], " \n"[i==n]);
return ;
}

Codeforces 741 D - Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths的更多相关文章

  1. 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 ...

  2. 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 题意 给出一棵树,每条边上有一个字符,字符集大小只 ...

  3. 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 ...

  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. 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的 ...

  6. 【42.86%】【codeforces 742D】Arpa's weak amphitheater and Mehrdad's valuable Hoses

    time limit per test1 second memory limit per test256 megabytes inputstandard input outputstandard ou ...

  7. 【CodeForces】741 D. Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths(dsu on tree)

    [题意]给定n个点的树,每条边有一个小写字母a~v,求每棵子树内的最长回文路径,回文路径定义为路径上所有字母存在一种排列为回文串.n<=5*10^5. [算法]dsu on tree [题解]这 ...

  8. 【题解】Arpa's letter-marked tree and Mehrdad's Dokhtar-kosh paths Codeforces 741D DSU on Tree

    Prelude 很好的模板题. 传送到Codeforces:(* ̄3 ̄)╭ Solution 首先要会DSU on Tree,不会的看这里:(❤ ω ❤). 众所周知DSU on Tree是可以用来处 ...

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

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

随机推荐

  1. linux----------fedora 27 如何启用输入法

    1.安装完成以后是自带了输入法的,但是需要启用. 一定要放到第一个位置,然后注销或者重启.

  2. CentOS 7 MySQL HA之DRBD

    一.DRBD简介 DRBD的全称为:Distributed ReplicatedBlock Device(DRBD)分布式块设备复制,DRBD是由内核模块和相关脚本而构成,用以构建高可用性的集群.其实 ...

  3. ERROR 1698 (28000): Access denied for user 'root'@'localhost'

    Some systems like Ubuntu, mysql is using by default the UNIX auth_socket plugin. Basically means tha ...

  4. BeyondCompare使用一段时间后会因“许可证密钥已被撤销:3281-0350“而无法使用

    解决方式: 1.用任意文本编辑软件打开“C:\Users\[Your User Name]\AppData\Roaming\Scooter Software\Beyond Compare 3\BCSt ...

  5. mysql索引类型(按存储结构划分)

    关于mysql索引类型,网上有很多相关的介绍,给人的感觉很乱.鄙人在翻阅相关书籍后,特意梳理了一下.哪里有不对的地方,欢迎指正! 1. B-Tree索引 它使用B-Tree数据结构来存储数据,实际上很 ...

  6. [转载]Oracle之xml的增删改查操作

    tip: xmltype函数是将clob字段转成xmltype类型的函数,若字段本身为xmltype类型则不需要引用xmltype()函数 同名标签用数组取值的方式获取,但起始值从1开始 一.查询(Q ...

  7. linux 看执行任务的一些邮件

    cat /var/spool/mail/root From root@hadoop01.localdomain Fri Apr 12 18:44:01 2019 Return-Path: <ro ...

  8. SpringBoot 项目打包分开lib,配置和资源文件

    原文地址:https://blog.csdn.net/u012811805/article/details/80878848 1 jar启动分离依赖lib和配置 先前发布boot项目的时候,改动一点东 ...

  9. 【数据下载】利用wget命令批量下载ftp文件和文件夹

    这是一个“”数据大发现”的时代,大家都在创造数据,使用数据以及分享数据,首先一步我们就需要从数据库download我们需要的数据. Ftp是一种常见的在线数据库,今天介绍一种可以批量下载文件夹的方法, ...

  10. Java8-Map

    1.Staff实体 public class Staff { private String name; private int age; private String address; public ...