dsu on tree(无讲解)
CF741D. Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths
分析:
- 最多有一个字符出现奇数次
- 维护某个状态下深度的最大值,注意是全局深度
- 写成非递归形式方便理解
代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cstdlib>
using namespace std;
#define N 500050
#define M (1<<22)
#define inf 0x3f3f3f3f
int head[N],to[N<<1],nxt[N<<1],cnt,n,val[N<<1];
int mx[M],siz[N],ans[N],son[N];
int dfn[N],idf[N],enp[N];
int nowans,dep[N],len[N];
inline void add(int u,int v,int w) {
to[++cnt]=v; nxt[cnt]=head[u]; head[u]=cnt; val[cnt]=w;
}
void df1(int x,int y) {
int i;
siz[x]=1; len[x]=len[y]+1;
dfn[x]=++dfn[0]; idf[dfn[0]]=x;
for(i=head[x];i;i=nxt[i]) if(to[i]!=y) {
dep[to[i]]=dep[x]^(1<<val[i]);
df1(to[i],x);
siz[x]+=siz[to[i]];
if(siz[to[i]]>siz[son[x]]) son[x]=to[i];
}
enp[x]=dfn[0];
}
void df2(int x,int y,int opt) {
int i;
for(i=head[x];i;i=nxt[i]) if(to[i]!=y&&to[i]!=son[x]) {
df2(to[i],x,0); ans[x]=max(ans[x],ans[to[i]]);
}
if(son[x]) {
df2(son[x],x,1);
ans[x]=max(ans[x],ans[son[x]]);
nowans=max(nowans,mx[dep[x]]-len[x]);
for(i=0;i<22;i++) nowans=max(nowans,mx[dep[x]^(1<<i)]-len[x]);
}
mx[dep[x]]=max(mx[dep[x]],len[x]);
for(i=head[x];i;i=nxt[i]) if(to[i]!=y&&to[i]!=son[x]) {
int t=to[i],j,p,k;
for(j=dfn[t];j<=enp[t];j++) {
p=idf[j];
nowans=max(nowans,mx[dep[p]]+len[p]-len[x]*2);
for(k=0;k<22;k++) nowans=max(nowans,mx[ dep[p]^(1<<k) ]+len[p]-len[x]*2);
}
for(j=dfn[t];j<=enp[t];j++) {
p=idf[j];
mx[dep[p]]=max(mx[dep[p]],len[p]);
}
}
ans[x]=max(ans[x],nowans);
if(!opt) {
nowans=-inf;
for(i=dfn[x];i<=enp[x];i++) mx[dep[idf[i]]]=-inf;
}
}
int main() {
memset(mx,0xc0,sizeof(mx));
scanf("%d",&n);
int i,x;
char op[4];
for(i=2;i<=n;i++) {
scanf("%d%s",&x,op);
add(x,i,op[0]-'a'); add(i,x,op[0]-'a');
}
df1(1,0);
df2(1,0,1);
for(i=1;i<=n;i++) printf("%d ",ans[i]);
}
BZOJ5457: 城市
代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cstdlib>
using namespace std;
#define N 400050
int head[N],to[N<<1],nxt[N<<1],n,m,cnt;
int a[N],b[N],dfn[N],idf[N],fa[N],enp[N],son[N],siz[N],top[N];
#define nc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++)
char buf[100000],*p1,*p2;
inline int rd() {
int x=0;char c=nc();
while(c<48)c=nc();
while(c>47)x=((x+(x<<2))<<1)+(c^48),c=nc();
return x;
}
inline void add(int u,int v) {
to[++cnt]=v; nxt[cnt]=head[u]; head[u]=cnt;
}
void df1(int x,int y) {
int i; fa[x]=y;
siz[x]=1; dfn[x]=++dfn[0]; idf[dfn[0]]=x;
for(i=head[x];i;i=nxt[i]) if(to[i]!=y) {
df1(to[i],x);
siz[x]+=siz[to[i]];
if(siz[to[i]]>siz[son[x]]) son[x]=to[i];
}
enp[x]=dfn[0];
}
int nowans,ans[N],c[N],tot[N];
void df2(int x) {
int i,j,t,lim;
for(i=head[x];i;i=nxt[i]) if(to[i]!=son[x]&&to[i]!=fa[x]) {
df2(to[i]);
}
if(son[x]) df2(son[x]);
c[a[x]]+=b[x];
if(c[nowans]<c[a[x]]||(c[nowans]==c[a[x]]&&nowans>a[x])) {
nowans=a[x];
}
for(i=head[x];i;i=nxt[i]) if(to[i]!=son[x]&&to[i]!=fa[x]) {
t=to[i],lim=enp[t];
for(j=dfn[t];j<=lim;j++) {
int p=idf[j];
c[a[p]]+=b[p];
if(c[nowans]<c[a[p]]||(c[nowans]==c[a[p]]&&nowans>a[p])) {
nowans=a[p];
}
}
}
ans[x]=nowans; tot[x]=c[nowans];
if(son[fa[x]]!=x) {nowans=0;for(lim=enp[x],i=dfn[x];i<=lim;i++) c[a[idf[i]]]=0;}
}
char pbuf[4000000],*pp=pbuf;
int sta[30],tp;
void write(int x) {
if(x<0) *pp++='-',x=-x;
do {sta[++tp]=x%10,x/=10;}while(x);
while(tp)*pp++=sta[tp--]+'0';
}
int main() {
n=rd(),m=rd();
int i,x,y;
for(i=1;i<n;i++) x=rd(),y=rd(),add(x,y),add(y,x);
for(i=1;i<=n;i++) a[i]=rd(),b[i]=rd();
df1(1,0); df2(son[0]=1);
for(i=1;i<=n;i++) {
write(ans[i]); *pp++=' '; write(tot[i]); *pp++='\n';
}
fwrite(pbuf,1,pp-pbuf,stdout);
}
dsu on tree(无讲解)的更多相关文章
- dsu on tree:关于一类无修改询问子树可合并问题
dsu on tree:关于一类无修改询问子树可合并问题 开始学长讲课的时候听懂了但是后来忘掉了....最近又重新学了一遍 所谓\(dsu\ on\ tree\)就是处理本文标题:无修改询问子树可合并 ...
- dsu on tree (树上启发式合并) 详解
一直都没出过算法详解,昨天心血来潮想写一篇,于是 dsu on tree 它来了 1.前置技能 1.链式前向星(vector 建图) 2.dfs 建树 3.剖分轻重链,轻重儿子 重儿子 一个结点的所有 ...
- Dsu on Tree
这个属于一种技巧,可以解决类似于子树询问无修改可离线的问题,一些点分治的问题也可以用Dsu on Tree解决,并且常数较小,代码复杂度低,很具有可写性. 整体上的意思就是继承重儿子的信息,暴力修改轻 ...
- dsu on tree题表
dsu on tree,又名树上启发式合并.重链剖分,是一类十分实用的trick,它常常可以作为一些正解的替代算法: 1.DFS序+线段树/主席树/线段树合并 2.对DFS序分块的树上莫队 3.长链剖 ...
- DSU on Tree浅谈
DSU on tree 在之前的一次比赛中,学长向我们讲了了这样一个神奇的思想:DSU on tree(树上启发式合并),看上去就非常厉害--但实际上是非常暴力的一种做法;不过暴力只是看上去暴力,它在 ...
- dsu on tree学习笔记
前言 一次模拟赛的\(T3\):传送门 只会\(O(n^2)\)的我就\(gg\)了,并且对于题解提供的\(\text{dsu on tree}\)的做法一脸懵逼. 看网上的其他大佬写的笔记,我自己画 ...
- 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,求每个子树中最长的边,满 ...
- CF 570D. Tree Requests [dsu on tree]
传送门 题意: 一棵树,询问某棵子树指定深度的点能否构成回文 当然不用dsu on tree也可以做 dsu on tree的话,维护当前每一个深度每种字母出现次数和字母数,我直接用了二进制.... ...
- [dsu on tree]【学习笔记】
十几天前看到zyf2000发过关于这个的题目的Blog, 今天终于去学习了一下 Codeforces原文链接 dsu on tree 简介 我也不清楚dsu是什么的英文缩写... 就像是树上的启发式合 ...
随机推荐
- 图片压缩CompressUtil解析
CompressUtil 流程图: CompressUtil 类 具体解释 public class CompressUtil { /** * 终于封装的压缩方法 * @param imgPath * ...
- 百度富文本编辑器Ueditor上传图片时标签中添加宽高
ueditor.all.js中:直接搜索callback() function callback(){ try{ var link, json, loader, body = (iframe.cont ...
- easyUI中 datagrid 一列字比较多时,出现省略符号
当数据比较多为,出现省略符号 <style type="text/css"> .datagrid-cell, .datagrid-cell-gro ...
- EF Core 日志跟踪sql语句
EF Core 日志跟踪sql语句 官方文档链接:https://docs.microsoft.com/en-us/ef/core/miscellaneous/logging 1.新增自定义ILogg ...
- IntelliJ IDEA打可执行jar包
<plugins> <plugin> <artifactId>maven-assembly-plugin</artifactId> <config ...
- smarty静态缓存
缓存能让程序访问起来更加快速,调数据库的数量变少,不能实时的跟数据库同步, 一般缓存文件都放在smarty文件下cach文件夹中: 建立缓存的PHP和HTML文件: 先编辑PHP文件来查询显示数据库当 ...
- python之Matplotlib 和Numpy
1.matplotlib http://www.cnblogs.com/TensorSense/p/6802280.html https://wenku.baidu.com/view/e1c15c9d ...
- 使用OpenSessionInViewFilter的注意事项
假设在你的应用中Hibernate是通过spring 来管理它的session.如果在你的应用中没有使用OpenSessionInViewFilter或者OpenSessionInViewInterc ...
- 九度OJ 1053:互换最大最小数 (基础题)
时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:6613 解决:2676 题目描述: 输入一个数n,然后输入n个数值各不相同,调换数组中最大和最小的两个数,然后输出. 输入: 测试数据有多组 ...
- kafka source type
https://flume.apache.org/FlumeUserGuide.html # example.conf: A single-node Flume configuration # Nam ...