BZOJ 4679/Hdu5331 Simple Problem LCT or 树链剖分
4679: Hdu5331 Simple Problem
题意:

考场上,看到这道题就让我想起BZOJ4712洪水。然后思路就被带着飞起了,完全没去考虑一条链的情况,于是GG.
解法:先考虑一条链的做法,可以用线段树维护一下,需要保留的信息:$F[0/1][0/1]$表示左端点不选/选,右端点不选/选 的最多人数。在树上的做法,可以在重链上用线段树维护,对于轻边,就暴力更新其父亲(每个点存下了其轻边的答案),然后接着往上更新重链。
于是先离线,$O(n\log n)$。
在线做法,将上述做法扩展到LCT上。复杂度还是$O(n\log n)$
代码很丑 ⁄(⁄ ⁄•⁄ω⁄•⁄ ⁄)⁄
#include< cstdio > #define gec getchar
#define FILE(F) freopen(F".in","r",stdin),freopen(F".out","w",stdout)
#define DEBUG fprintf(stderr,"Passing [%s] in Line (%d)\n",__FUNCTION__,__LINE__); typedef long long ll;
template
inline void read(T&x)
{
x=0;bool f=0;char c=gec();
for(;c<'0'||c>'9';c=gec())f=(c=='-');
for(;c>='0'&&c<='9';c=gec())x=x*10+c-'0';
x=f?-x:x;
}
const int MAXN(300010),INF(0x73f3f3f);
int n,ty,f,Father[MAXN],root;//编号全部+1
int max(int a,int b){return a>b?a:b;}
struct Data{int f[2][2];}zero;
struct LCT
{
int fa[MAXN],nx[MAXN][2],F[MAXN],G[MAXN];//轻儿子的答案
Data val[MAXN];//[1/0][1/0] 顶端选/不选 尾端选/不选
int which(int x){if(nx[fa[x]][0]==x)return 0;if(nx[fa[x]][1]==x)return 1;return -1;}
void update(int x)
{
if(nx[x][0]&&nx[x][1])
for(int i=0;i<=1;i++) for(int j=0;j<=1;j++)
{
val[x].f[i][j]=max(max(val[nx[x][0]].f[i][1],val[nx[x][0]].f[i][0])+
max(val[nx[x][1]].f[1][j],val[nx[x][1]].f[0][j])+F[x],
val[nx[x][0]].f[i][0]+val[nx[x][1]].f[0][j]+G[x]);
}
else
if(nx[x][0])
for(int i=0;i<=1;i++)
{
val[x].f[i][0]=max(val[nx[x][0]].f[i][0],val[nx[x][0]].f[i][1])+F[x];
val[x].f[i][1]=val[nx[x][0]].f[i][0]+G[x];
}
else
if(nx[x][1])
for(int i=0;i<=1;i++)
{
val[x].f[0][i]=max(val[nx[x][1]].f[0][i],val[nx[x][1]].f[1][i])+F[x];
val[x].f[1][i]=val[nx[x][1]].f[0][i]+G[x];
}else
{
val[x].f[1][1]=G[x]; val[x].f[0][0]=F[x];
val[x].f[0][1]=val[x].f[1][0]=0;
}
}
void rotate(int x)
{
int ff=fa[x],fafa=fa[ff],fd=which(ff),xd=which(x);
fa[nx[x][xd^1]]=ff;
nx[ff][xd]=nx[x][xd^1];
nx[x][xd^1]=ff;fa[ff]=x;
fa[x]=fafa;if(fd!=-1)nx[fafa][fd]=x;
update(ff);
}
void splay(int x)
{
if(!x)return;
while(which(x)!=-1)
{
if(which(fa[x])==-1)rotate(x);
else
{
if(which(fa[x])^which(x))rotate(fa[x]),rotate(x);
else rotate(x),rotate(x);
}
}
update(x);
}
void Look()
{
for(int i=1;i<=n+1;i++)
{
fprintf(stderr,"i:%d Fa:%d n0:%d n1:%d F:%d G:%d\n",i,fa[i],nx[i][0],nx[i][1],F[i],G[i]);
fprintf(stderr,"v00:%d v01:%d v10:%d v11:%d\n",val[i].f[0][0],val[i].f[0][1],val[i].f[1][0],val[i].f[1][1]);
}
}
void access(int x,int t)
{
int Fr,Gr,Fl=0,Gl=0,Tf,Tg;
while(x)
{
splay(x);update(nx[x][1]);
// fprintf(stderr,"x:%d\n",x);
Fr=max(val[nx[x][1]].f[0][0],val[nx[x][1]].f[0][1]);
Gr=max(val[nx[x][1]].f[1][0],val[nx[x][1]].f[1][1]);
// fprintf(stderr,"Fr:%d Gr:%d\n",Fr,Gr);
// fprintf(stderr,"Fl:%d Gl:%d\n",Fl,Gl);
Tf=max(val[x].f[0][0],val[x].f[0][1]);
Tg=max(val[x].f[1][0],val[x].f[1][1]);
// fprintf(stderr,"Tf:%d Tg:%d\n",Tf,Tg);
F[x]+=max(Fr,Gr);G[x]+=Fr;
F[x]-=max(Fl,Gl),G[x]-=Fl;
Fl=Tf; Gl=Tg;
nx[x][1]=t;update(x);
t=x;x=fa[x];
}
splay(1);
// Look();
}
void link(int a,int b)//a is b's father
{
fa[b]=a; access(a,b);
}
void New(int x)
{F[x]=0;G[x]=1;update(x);}
int ask(int x)
{
splay(x);
return max(val[x].f[0][0],max(val[x].f[1][1],max(val[x].f[1][0],val[x].f[0][1])));
}
}tree;
int Ans;
void Back()
{
for(int i=1;i<=n+1;i++)
{
tree.fa[i]=tree.nx[i][0]=tree.nx[i][1]=tree.F[i]=tree.G[i]=0;
tree.val[i]=zero;
}
}
int main()
{
#ifndef ONLINE_JUDGE
FILE("party");
#endif
while(scanf("%d",&n)!=EOF)
{
n--;Back();
root=1;tree.New(1);
for(int i=2;i<=n+1;i++)
{
read(f);
tree.New(i);
tree.link(++f,i);
// fprintf(stderr,"a:%d b:%d\n",f,i);
Ans=tree.ask(1);
printf("%d\n",Ans);
}
}
return 0;
}
BZOJ 4679/Hdu5331 Simple Problem LCT or 树链剖分的更多相关文章
- BZOJ.4034 [HAOI2015]树上操作 ( 点权树链剖分 线段树 )
BZOJ.4034 [HAOI2015]树上操作 ( 点权树链剖分 线段树 ) 题意分析 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 ...
- [HDU 5293]Tree chain problem(树形dp+树链剖分)
[HDU 5293]Tree chain problem(树形dp+树链剖分) 题面 在一棵树中,给出若干条链和链的权值,求选取不相交的链使得权值和最大. 分析 考虑树形dp,dp[x]表示以x为子树 ...
- BZOJ 2402 陶陶的难题II (树链剖分、线段树、凸包、分数规划)
毒瘤,毒瘤,毒瘤-- \(30000\)这个数据范围,看上去就是要搞事的啊... 题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=2402 ...
- bzoj 3626 [LNOI2014]LCA(离线处理+树链剖分,线段树)
3626: [LNOI2014]LCA Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1272 Solved: 451[Submit][Status ...
- bzoj 3631 松鼠的新家 (树链剖分)
链接: https://www.lydsy.com/JudgeOnline/problem.php?id=3631 思路: 直接用树链剖分求每一次运动,因为这道题只需要区间增添,单点求值,没必要用线段 ...
- bzoj 4326: NOIP2015 运输计划(二分+树链剖分)
传送门 题解: 树链剖分快速求解任意两点间的路径的权值和: 然后,二分答案: 此题的难点是如何快速求解重合路径? 差分数组可以否??? 在此之前先介绍一下相关变量: int fa[maxn]; int ...
- bzoj 3637: Query on a tree VI 树链剖分 && AC600
3637: Query on a tree VI Time Limit: 8 Sec Memory Limit: 1024 MBSubmit: 206 Solved: 38[Submit][Sta ...
- BZOJ 3631: [JLOI2014]松鼠的新家( 树链剖分 )
裸树链剖分... ------------------------------------------------------------------- #include<bits/stdc++ ...
- 【BZOJ】1146: [CTSC2008]网络管理Network(树链剖分+线段树套平衡树+二分 / dfs序+树状数组+主席树)
http://www.lydsy.com/JudgeOnline/problem.php?id=1146 第一种做法(时间太感人): 第二种做法(rank5,好开心) ================ ...
随机推荐
- 解决SharePoint2013产品过期问题
作者:huangtao2011 引用:http://blog.csdn.net/huangtao2011/article/details/27528101 今天使用SharePoint 2013创建页 ...
- 4 Values whose Sum is 0(枚举+二分)
The SUM problem can be formulated as follows: given four lists A, B, C, D of integer values, compute ...
- Jenkins自动化CI CD流水线之1--介绍与安装
第1章 大纲 CI/CD, DevOps介绍 Git安装与使用 Jenkins安装与使用 权限管理 参数化构建 Master-Slave 流水线(Pipeline) 邮件通知 应用案例 自动发布PHP ...
- MB Star C5 Functions
The MB STAR C5 notion and brand combination for hardware and software program components will be the ...
- 大型分布式java应用与SOA
1.基于消息方式.远程调用方式的架构带来的问题: 1.1 系统多元化的问题 [解决]: 对共用逻辑部分进行抽象: 1.2 系统访问量.数据量上涨后带来的问题 [解决]: 拆分系统: 1.3 在构建共用 ...
- GRE新东方推荐学习方法(2010年左右)
单词:新东方新版红宝书(<NEW GRE 词汇精选>),不用<再要你命三个> 填空:新东方绿皮书(扎实的词汇量) 阅读:1 新东方绿皮书:2 <GRE阅读 39+3全攻略 ...
- RTT之内存管理及异常中断
内存管理分静态内存管理和动态内存管理(根据大小又分2种) 静态内存管理:创建.删除.初始化.解绑.申请和释放.初始化内存池是属于静态内存管理,与创建内存池不同的是,此处内存池对象所使用的内存空间是由用 ...
- bcc-tools安装
1 一. 安装cmake cmake是一种跨平台的编译工具,安装过程如下: 下载源码包:https://cmake.org/files/v3.8/cmake-3.8.0.tar.g ...
- LeetCode 870.优势洗牌(C++)
给定两个大小相等的数组 A 和 B,A 相对于 B 的优势可以用满足 A[i] > B[i] 的索引 i 的数目来描述. 返回 A 的任意排列,使其相对于 B 的优势最大化. 示例 1: 输入: ...
- 牛客网Java刷题知识点之匿名对象、匿名对象的内存结构图、匿名对象的应用场景、匿名对象的使用、匿名对象的简单例子、匿名对象要注意的事项
不多说,直接上干货! 什么是匿名对象? 答: 没有名字的实体,也就是该实体没有对应的变量名引用. 没有名字的实体,没有引用类型变量指向的对象称作为匿名对象. 正常的,是 Car car = new ...