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(无讲解)的更多相关文章

  1. dsu on tree:关于一类无修改询问子树可合并问题

    dsu on tree:关于一类无修改询问子树可合并问题 开始学长讲课的时候听懂了但是后来忘掉了....最近又重新学了一遍 所谓\(dsu\ on\ tree\)就是处理本文标题:无修改询问子树可合并 ...

  2. dsu on tree (树上启发式合并) 详解

    一直都没出过算法详解,昨天心血来潮想写一篇,于是 dsu on tree 它来了 1.前置技能 1.链式前向星(vector 建图) 2.dfs 建树 3.剖分轻重链,轻重儿子 重儿子 一个结点的所有 ...

  3. Dsu on Tree

    这个属于一种技巧,可以解决类似于子树询问无修改可离线的问题,一些点分治的问题也可以用Dsu on Tree解决,并且常数较小,代码复杂度低,很具有可写性. 整体上的意思就是继承重儿子的信息,暴力修改轻 ...

  4. dsu on tree题表

    dsu on tree,又名树上启发式合并.重链剖分,是一类十分实用的trick,它常常可以作为一些正解的替代算法: 1.DFS序+线段树/主席树/线段树合并 2.对DFS序分块的树上莫队 3.长链剖 ...

  5. DSU on Tree浅谈

    DSU on tree 在之前的一次比赛中,学长向我们讲了了这样一个神奇的思想:DSU on tree(树上启发式合并),看上去就非常厉害--但实际上是非常暴力的一种做法;不过暴力只是看上去暴力,它在 ...

  6. dsu on tree学习笔记

    前言 一次模拟赛的\(T3\):传送门 只会\(O(n^2)\)的我就\(gg\)了,并且对于题解提供的\(\text{dsu on tree}\)的做法一脸懵逼. 看网上的其他大佬写的笔记,我自己画 ...

  7. 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,求每个子树中最长的边,满 ...

  8. CF 570D. Tree Requests [dsu on tree]

    传送门 题意: 一棵树,询问某棵子树指定深度的点能否构成回文 当然不用dsu on tree也可以做 dsu on tree的话,维护当前每一个深度每种字母出现次数和字母数,我直接用了二进制.... ...

  9. [dsu on tree]【学习笔记】

    十几天前看到zyf2000发过关于这个的题目的Blog, 今天终于去学习了一下 Codeforces原文链接 dsu on tree 简介 我也不清楚dsu是什么的英文缩写... 就像是树上的启发式合 ...

随机推荐

  1. linux - console/terminal/virtual console/pseudo terminal ...

    http://en.wikipedia.org/wiki/System_console System console Knoppix system console showing the boot p ...

  2. Away3D引擎学习笔记(一)资源加载解析块

    前文:Away3D断断续续用了一段时间了,三维相关的很多算法,计算转换还是有点绕,整理些自己觉得还有点意思东西,希望大家有用. 三维开始,Away3D构架你场景那几行代码各处都有,这里就不copy了, ...

  3. jQuery Validate(三)

    这里,我们再说说radio.checkbox.select的验证方式. 1.用新版的写法进行验证. <!DOCTYPE html> <html> <head> &l ...

  4. SpringBoot学习——运行原理学习及自定义Starter pom

    例如:pom文件 导入redis jar包 springboot怎么识别和集成? https://blog.csdn.net/flygoa/article/details/68484439 https ...

  5. php nginx超时出错

    执行PHP操作大文件insert mysql数据库时,出现这个错误提示 The page you are looking for is temporarily unavailable.Please t ...

  6. JavaWeb学习总结第四篇--Servlet开发

    Servlet开发 用户在浏览器中输入一个网址并回车,浏览器会向服务器发送一个HTTP请求.服务器端程序接受这个请求,并对请求进行处理,然后发送一个回应.浏览器收到回应,再把回应的内容显示出来.这种请 ...

  7. PHP百分号转小数

    <?php $a = "20.544545%"; echo (float)$a/100; ?>

  8. Android Thread.UncaughtExceptionHandler异常消息捕获

    public void uncaughtException(Thread thread, Throwable ex) { //处理异常 Log.e("崩溃",thread.getN ...

  9. python之异步IO

    协程的用武之地 并发量较大的系统和容易在IO方面出现瓶颈(磁盘IO,网络IO),采用多线程.多进程可以解决这个问题,当然线程.进程的切换时很消耗资源的.最好的解决方案是使用单线程方式解决并发IO问题- ...

  10. c++动态绑定的技术实现

    1 什么是动态绑定 有一个基类,两个派生类,基类有一个virtual函数,两个派生类都覆盖了这个虚函数.现在有一个基类的指针或者引用,当该基类指针或者引用指向不同的派生类对象时,调用该虚函数,那么最终 ...