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. .Net Core:Middleware中间件管道

    .NetCore中的Middleware是装配到管道处理请求和响应的组件:每个组件都可以决定是否继续进入下一个管道.并且可以在进入下一个管道前后执行逻辑: 最后一个管道或者中断管道的中间件叫终端中间件 ...

  2. 配置成功java11后安装eclipse失败

    前提是 1.java是成功配置的, 2.看清楚32bit,还是64bit,需要一致 THEN 方法一:去安装java11之前的版本,正确配置环境 方法二:java11中没有jre(不打紧).所以需要直 ...

  3. JavaWeb初级进阶高级学习方向计划

    阶段1 语言基础 课程一.Java负基础扫盲课 1.初识Java 本课程从java开发环境配置开始,讲解了java语法基础 .类和面向对象.面向对象编程三大特性:封装.继承.多态.建议零基础学员从本课 ...

  4. js中的this指向问题(小计)

    this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定,this最终指向调用它的对象. 1.函数调用模式 当一个函数并非一个对象的属性时,那么它就是被当做函数来调用的.在此种模式下,t ...

  5. Vue渐进式JavaScript 框架

    1. Vue简介 1.1  初步了解Vue.js框架 Vue.js (读音 /vjuː/,类似于 view) 是一种轻量级前端MVVM框架.同时吸收了React(组件化)和Angular(灵活指令页面 ...

  6. C# Json处理相关

    最近工作中遇到的Json问题确实很头大,主要是各种转义符的处理,想了一种通用的方式,来处理任意转移方式的Json字符串: /// <summary> /// 去除返回值中的转义符,返回js ...

  7. 查看Python、flask 版本

    查看Django版本检查是否安装成功,可以在dos下查看Django版本. 1.输入python 2.输入import django3.输入django.get_version() 查看flask版本 ...

  8. MVC 使用缓存

    public AController() { ViewBag[); } private List<BlogsClass> GetClass(int parentId) { List< ...

  9. Gradle's dependency cache may be corrupt

    原因分析: 当前Android studio 安装或者升级后配置的Gradle版本不对.可以打开安装目录下\Android\Android Studio\gradle\查看当前已有最新的版本.例如下图 ...

  10. PHP的openssl加密

    PHP的openssl扩展 openssl扩展使用openssl加密扩展包,封装了多个用于加密解密相关的PHP函数,极大地方便了对数据的加密解密. 常用的函数有: 对称加密相关: string ope ...