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是什么的英文缩写... 就像是树上的启发式合 ...
随机推荐
- CentOS6 图形界面(gnome)安装(转)
CentOS6相对于CentOS5的安装有了不少的进步,有不少默认的选项可以选择,如: Desktop :基本的桌面系统,包括常用的桌面软件,如文档查看工具. Minimal Desktop :基本的 ...
- Android网络编程Socket【实例解析】
Socket 事实上和JavaWeb 里面的Socket一模一样 建立客服端,server端,server开一个port供客服端訪问 第一步创建server端:(这里把为了便于解说.把server端, ...
- 【Python】用Python打开IE、谷歌等浏览器报错及解决办法
以IE浏览器为例: 当Python Shell输入下面代码时: >>> # coding=utf-8 >>> from selenium import webdri ...
- C#下的摄像机标定
前言:计算机视觉的基本任务之一是从摄像机获取的图像信息出发计算三维空间中物体的几何信息,并由此重建和识别物体,而空间物体表面某点的三维几何位置与其在图像中对应点之间的相互关系是由摄像机成像的几何模型决 ...
- pjax简单实例
ajax缺点是破坏了浏览器的前进后退,因为ajax的请求不会留在历史记录中.pjax就不一样了,pjax被解释成ajax+pushState的封装,因为它把ajax的请求写入历史记录,并反映在地址栏, ...
- django部署到apache上(非常重要的,3者版本要一致,是32位就都要是32位的)
网上把django部署到apache的文章挺多的,但是按照大家的操作,并没有一次就成功,还是遇到了一些问题,这里主要有以下几个情况. 1.网上找到的mod_wsgi的版本问题,导致动态库加载不上. 2 ...
- 【BZOJ2654】tree 二分+最小生成树
[BZOJ2654]tree Description 给你一个无向带权连通图,每条边是黑色或白色.让你求一棵最小权的恰好有need条白色边的生成树. 题目保证有解. Input 第一行V,E,need ...
- bmdiff snappy lzw gzip
https://github.com/google/snappy Introduction [速度第一,压缩比适宜] [favors speed over compression ratio] Sna ...
- python cookbook第三版学习笔记九:函数
接受任意数量参数的函数. 当传入函数的参数个数很多的时候,在函数定义的时候不需要为每一个参数定义一个变量,可以用*rest的方式来包含多余的参数. 如下面的代码,*rest包含了2,3,4这3个参数. ...
- 关于wx.redirectTo、wx.navigateTo失效问题
问题:在app.json页面中若配置了tabBar,并且要跳转的目标页面也在tabBar中时,那么常用的几种页面跳转方式便失效了.即不能跳转到tabBar中定义的页面. 解决办法:若要跳转至tabBa ...