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. 多个页面引用公共的头部 header.html 和尾部 footer.html

    方法:通过load()函数,引入公共头部和尾部文件; js代码预览: $(".headerPage").load("header.html"); $(" ...

  2. Qt QDateEdit QDateTimeEdit

    展示一个效果,然后附上一个“笑话~~”...回想起来都是搞笑的. 笑话来了,,,,几个月前,为了做出时间选择界面,我亲自“创造”了一个...今天发现了QDateEdit的属性CalendarPopup ...

  3. Git 命令及git服务器

    Linux 服务器上安装git yum -y install git git config  --global user.name "name" git config  --glo ...

  4. nodejs:导出Excel和解析导入的Excel

    用的是koa2框架,但好好处理一下,用express框架也是可以的.导出的Excel是xlsx的格式,解析导入Excel的有xlsx和csv格式.通常导入Excel是要上传的,然后获取文件的路径,这里 ...

  5. vue生命周期钩子函数

    <template> <div> <h2>this is from C.vue</h2> </div> </template> ...

  6. Junit4 之 Assert 静态方法介绍

    Junit中的assert方法全部放在Assert类中,总结一下junit类中assert方法的分类. 1.assertTrue/False([String message,]boolean cond ...

  7. 命令行创建cocos2d-x的工程

    1. 命令行创建cocos lua工程cocos new MyGame -p com.your_company.mygame -l lua2. 进入工程目录, 编译运行时库cocos compile ...

  8. GO : 斐波纳契数列

    package main import "fmt" // fibonacci is a function that returns // a function that retur ...

  9. npm install --save 、--save-dev 、-D、-S 的区别

    备注:<=> 意为等价于: 1.npm install <=> npm i --save   <=> -S --save-dev  <=> -D npm ...

  10. sqlServer区分大小写查询

    sql server默认不区分大小写查询,但是有的时候部分查询语句却需要区分大小写查询,这个时候就需要进行一些特殊处理.区分大小写主要分两种方法. 转二进制判断 select * from table ...