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是什么的英文缩写... 就像是树上的启发式合 ...
随机推荐
- linux - console/terminal/virtual console/pseudo terminal ...
http://en.wikipedia.org/wiki/System_console System console Knoppix system console showing the boot p ...
- Away3D引擎学习笔记(一)资源加载解析块
前文:Away3D断断续续用了一段时间了,三维相关的很多算法,计算转换还是有点绕,整理些自己觉得还有点意思东西,希望大家有用. 三维开始,Away3D构架你场景那几行代码各处都有,这里就不copy了, ...
- jQuery Validate(三)
这里,我们再说说radio.checkbox.select的验证方式. 1.用新版的写法进行验证. <!DOCTYPE html> <html> <head> &l ...
- SpringBoot学习——运行原理学习及自定义Starter pom
例如:pom文件 导入redis jar包 springboot怎么识别和集成? https://blog.csdn.net/flygoa/article/details/68484439 https ...
- php nginx超时出错
执行PHP操作大文件insert mysql数据库时,出现这个错误提示 The page you are looking for is temporarily unavailable.Please t ...
- JavaWeb学习总结第四篇--Servlet开发
Servlet开发 用户在浏览器中输入一个网址并回车,浏览器会向服务器发送一个HTTP请求.服务器端程序接受这个请求,并对请求进行处理,然后发送一个回应.浏览器收到回应,再把回应的内容显示出来.这种请 ...
- PHP百分号转小数
<?php $a = "20.544545%"; echo (float)$a/100; ?>
- Android Thread.UncaughtExceptionHandler异常消息捕获
public void uncaughtException(Thread thread, Throwable ex) { //处理异常 Log.e("崩溃",thread.getN ...
- python之异步IO
协程的用武之地 并发量较大的系统和容易在IO方面出现瓶颈(磁盘IO,网络IO),采用多线程.多进程可以解决这个问题,当然线程.进程的切换时很消耗资源的.最好的解决方案是使用单线程方式解决并发IO问题- ...
- c++动态绑定的技术实现
1 什么是动态绑定 有一个基类,两个派生类,基类有一个virtual函数,两个派生类都覆盖了这个虚函数.现在有一个基类的指针或者引用,当该基类指针或者引用指向不同的派生类对象时,调用该虚函数,那么最终 ...