#树上启发式合并,trie#JZOJ 5363 生命之树

分析
考虑按位处理,
如果熟悉dsu的话可以发现这道题能够用dsu做,
再用两个trie分别维护该位为0或1的字符串,
重儿子可以按照子树字符串的总长计算
代码
#include <cstdio>
#include <cctype>
#include <cstring>
#define rr register
using namespace std;
const int N=100011,M=500011; typedef long lll; char s[M];
struct node{int y,next;}e[N<<1]; lll now,ans[N],siz[N];
int as[N],a[N],S,et=1,n,r[N],root,dep[N],fat[N],big[N];
inline signed iut(){
rr int ans=0; rr char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
return ans;
}
inline void print(lll ans){
if (ans>9) print(ans/10);
putchar(ans%10+48);
}
struct Trie{
int tot,trie[M][26],cnt[M];
inline void Clear(){memset(trie[1],0,sizeof(trie[1])),cnt[tot=1]=0;}
inline void Insert(int L,int R){
rr int p=1; ++cnt[p];
for (rr int i=L;i<R;++i){
if (!trie[p][s[i]-97]){
trie[p][s[i]-97]=++tot,cnt[tot]=0,
memset(trie[tot],0,sizeof(trie[tot]));
}
p=trie[p][s[i]-97],++cnt[p];
}
}
inline signed query(int L,int R){
rr int p=1,sum=0;
for (rr int i=L;i<R;++i){
p=trie[p][s[i]-97];
if (!p) return sum;
sum+=cnt[p];
}
return sum;
}
}trie0,trie1;
inline void dfs1(int x,int fa){
dep[x]=dep[fa]+1,fat[x]=fa,siz[x]=r[x]-r[x-1];
for (rr int i=as[x],SIZ=-1;i;i=e[i].next)
if (e[i].y!=fa){
dfs1(e[i].y,x);
siz[x]+=siz[e[i].y];
if (siz[e[i].y]>SIZ) big[x]=e[i].y,SIZ=siz[e[i].y];
}
}
inline void updqry(int x){
for (rr int i=as[x];i;i=e[i].next)
if (e[i].y!=fat[x]&&e[i].y!=root) updqry(e[i].y);
if (a[x]&S) now+=trie0.query(r[x-1],r[x]),trie1.Insert(r[x-1],r[x]);
else now+=trie1.query(r[x-1],r[x]),trie0.Insert(r[x-1],r[x]);
}
inline void dfs2(int x,int opt){
for (rr int i=as[x];i;i=e[i].next)
if (e[i].y!=fat[x]&&e[i].y!=big[x]) dfs2(e[i].y,0);
if (big[x]) dfs2(big[x],1),root=big[x];
updqry(x),ans[x]+=now*S,root=0;
if (!opt) trie0.Clear(),trie1.Clear(),now=0;
}
signed main(){
freopen("tree.in","r",stdin);
freopen("tree.out","w",stdout);
n=iut(),trie0.tot=trie1.tot=r[0]=1;
for (rr int i=1;i<=n;++i) a[i]=iut();
for (rr int i=1;i<=n;++i){
r[i]=r[i-1]; rr char c=getchar();
while (!isalpha(c)) c=getchar();
while (isalpha(c)) s[r[i]++]=c,c=getchar();
}
for (rr int i=1;i<n;++i){
rr int x=iut(),y=iut();
e[++et]=(node){y,as[x]},as[x]=et,
e[++et]=(node){x,as[y]},as[y]=et;
}
dfs1(1,0); for (S=1;S<N;S<<=1) dfs2(1,0);
for (rr int i=1;i<=n;++i) print(ans[i]),putchar(10);
return 0;
}
#树上启发式合并,trie#JZOJ 5363 生命之树的更多相关文章
- hdu6191(树上启发式合并)
hdu6191 题意 给你一棵带点权的树,每次查询 \(u\) 和 \(x\) ,求以 \(u\) 为根结点的子树上的结点与 \(x\) 异或后最大的结果. 分析 看到子树,直接上树上启发式合并,看到 ...
- 算法学习笔记(19): 树上启发式合并(DSU on tree)
树上启发式合并 DSU on tree,我也不知道DSU是啥意思 这是一种看似特别玄学的优化 可以把树上部分问题由 \(O(n^2)\) 优化到 \(O(n \log n)\). 例如 CodeFor ...
- dsu on tree 树上启发式合并 学习笔记
近几天跟着dreagonm大佬学习了\(dsu\ on\ tree\),来总结一下: \(dsu\ on\ tree\),也就是树上启发式合并,是用来处理一类离线的树上询问问题(比如子树内的颜色种数) ...
- 树上启发式合并(dsu on tree)学习笔记
有丶难,学到自闭 参考的文章: zcysky:[学习笔记]dsu on tree Arpa:[Tutorial] Sack (dsu on tree) 先康一康模板题吧:CF 600E($Lomsat ...
- 神奇的树上启发式合并 (dsu on tree)
参考资料 https://www.cnblogs.com/zhoushuyu/p/9069164.html https://www.cnblogs.com/candy99/p/dsuontree.ht ...
- Codeforces 208E - Blood Cousins(树上启发式合并)
208E - Blood Cousins 题意 给出一棵家谱树,定义从 u 点向上走 k 步到达的节点为 u 的 k-ancestor.多次查询,给出 u k,问有多少个与 u 具有相同 k-ance ...
- Codeforces 600E - Lomsat gelral(树上启发式合并)
600E - Lomsat gelral 题意 给出一颗以 1 为根的树,每个点有颜色,如果某个子树上某个颜色出现的次数最多,则认为它在这课子树有支配地位,一颗子树上,可能有多个有支配的地位的颜色,对 ...
- csu1811(树上启发式合并)
csu1811 题意 给定一棵树,每个节点有颜色,每次仅删掉第 \(i\) 条边 \((a_i, b_i)\) ,得到两颗树,问两颗树节点的颜色集合的交集. 分析 转化一下,即所求答案为每次删掉 \( ...
- CF EDU - E. Lomsat gelral 树上启发式合并
学习:http://codeforces.com/blog/entry/44351 E. Lomsat gelral 题意: 给定一个以1为根节点的树,每个节点都有一个颜色,问每个节点的子树中,颜色最 ...
- 【CodeChef EDGEST】Edges in Spanning Trees(树链剖分+树上启发式合并)
点此看题面 大致题意: 给你两棵\(n\)个点的树,对于第一棵树中的每条边\(e_1\),求存在多少条第二棵树中的边\(e_2\),使得第一棵树删掉\(e_1\)加上\(e_2\).第二棵树删掉\(e ...
随机推荐
- 使用winsw将jar包注册成windows服务
使用winsw将jar包注册成windows服务 注:exe文件作用:使用winsw将jar包注册成windows服务(下载地址https://github.com/winsw/winsw/relea ...
- 【webserver 前置知识 03】Linux网络编程入门其二,I/O多路复用
I/O多路复用 I/O多路复用使得程序能够同时监听多个文件描述符 LInux下实现I/O多路复用的系统调用主要由select.poll以及epoll(常问,要会自己写出来) 例子 阻塞等待 阻塞等待可 ...
- 【Azure 事件中心】Event Hubs中存在非常多的错误数据,是否能提前删除这些数据呢?
问题描述 因为一些特殊原因,Event Hub 里面堆积了很多不需要的数据事件,正常要等事件中的过期时间到后才有Event Hub自动删除掉,但希望能够尽快马上删除,有没有什么手动的方法吗? 问题解答 ...
- 【Azure 环境】记录使用Notification Hub,安卓手机收不到Push通知时的错误,Error_Code 30602 or 30608
问题描述 使用Azure Notification Hub + Baidu 推送遇见的两次报错为: 1. {"request_id":2921358089,"error_ ...
- 手把手教你蜂鸟e203协处理器的扩展
NICE协处理器 赛题要求: 对蜂鸟E203 RISC-V内核进行运算算子(譬如加解密算法.浮点运算.矢量运算等)的扩展,可通过NICE协处理器接口进行添加,也可直接实现RISC-V指令子集(譬如 ...
- Android学习之文件存储
•前言 任何一个应用程序,其实说白了就是在不停地和数据打交道,我们聊QQ.看新闻.刷微博,所关心的都是里面的数据, 没有数据的应用程序就变成了一个空壳子,对用户来说没有任何实际用途. 那么这些数据都是 ...
- 读书笔记:CSAPP 11章 网络编程
深入理解计算机系统 第11章 本章代码:Index of /afs/cs/academic/class/15213-f15/www/code/22-netprog2 其中包含本章课本示例代码,测试 T ...
- vue-helper 导致找到2个函数定义,跳转需要多点一下,禁用vue-helper即可
vue-helper 导致找到2个函数定义,跳转需要多点一下,禁用vue-helper即可
- 异步小工具 asyncTool
class asyncTool { constructor () { this.arr = [] this.ctx = {} } use (func) { const into = { func, n ...
- WPF之模板
目录 模板的内涵 数据的外衣DataTemplate UserControl例子 DataTemplate例子 控件的外衣 ControlTemplate 解剖控件 ItemsControl的Pane ...