CF860E Arkady and a Nobody-men

类比LNOI2014 LCA那个题,其实树剖可以过。。。。(用树状数组区间加区间求和更快!)

巧妙的nlogn做法是:

blog~

(其实第二个式子有锅,应当再加上dep[fa[x]])

对于同一层的考虑处理lca问题

一定要排个序处理

dfs是处理树上顺序的有力武器!

按dfs从小到大,一个x的前面的所有点的lca深度单调不降

可以用一个单调栈维护,只用维护:最后的位置(宽度),深度(键值),代表的点

如果和栈顶的代表点的lca深度比栈顶的键值小,那么pop栈顶,等价于把些点合并!

详见代码:

#include<bits/stdc++.h>
#define reg register int
#define il inline
#define fi first
#define se second
#define mk(a,b) make_pair(a,b)
#define numb (ch^'0')
#define pb push_back
#define solid const auto &
#define enter cout<<endl
#define pii pair<int,int>
using namespace std;
typedef long long ll;
template<class T>il void rd(T &x){
char ch;x=;bool fl=false;while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true);
for(x=numb;isdigit(ch=getchar());x=x*+numb);(fl==true)&&(x=-x);}
template<class T>il void output(T x){if(x/)output(x/);putchar(x%+'');}
template<class T>il void ot(T x){if(x<) putchar('-'),x=-x;output(x);putchar(' ');}
template<class T>il void prt(T a[],int st,int nd){for(reg i=st;i<=nd;++i) ot(a[i]);putchar('\n');}
namespace Modulo{
const int mod=;
int ad(int x,int y){return (x+y)>=mod?x+y-mod:x+y;}
void inc(int &x,int y){x=ad(x,y);}
int mul(int x,int y){return (ll)x*y%mod;}
void inc2(int &x,int y){x=mul(x,y);}
int qm(int x,int y=mod-){int ret=;while(y){if(y&) ret=mul(x,ret);x=mul(x,x);y>>=;}return ret;}
}
//using namespace Modulo;
namespace Miracle{
const int N=5e5+;
int n;
int fa[N][];
ll g[N];
struct node{
int nxt,to;
}e[N];
int hd[N],cnt;
void add(int x,int y){
e[++cnt].nxt=hd[x];
e[cnt].to=y;
hd[x]=cnt;
}
int dfn[N],df;
int dep[N];
vector<int>mem[N];
int mx;
void dfs(int x,int d){
dep[x]=d;
mx=max(mx,d);
mem[d].pb(x);
for(reg i=hd[x];i;i=e[i].nxt){
int y=e[i].to;
dfs(y,d+);
}
}
struct po{
int id,pos,d;
po(){}
po(int ii,int dd,int pp){
id=ii;pos=pp;d=dd;
}
}sta[N];
int top;
ll calc(){
if(!top) return ;
return (ll)(sta[top].pos-sta[top-].pos)*sta[top].d;
}
int lca(int x,int y){
if(dep[x]<dep[y]) swap(x,y);
for(reg j=;j>=;--j){
if(dep[fa[x][j]]>=dep[y]) x=fa[x][j];
}
if(x==y) return x;
for(reg j=;j>=;--j){
if(fa[x][j]!=fa[y][j]) x=fa[x][j],y=fa[y][j];
}
return fa[x][];
}
void sol(vector<int>&v){
int o=;
top=;
ll val=;
for(solid x:v){
if(!o){
++top;sta[top]=po(x,,);
}
else{
while(){
int y=lca(sta[top].id,x);
if(dep[y]>=sta[top].d){
++top;sta[top]=po(x,dep[y],o);break;
}
val-=calc();
--top;
}
val+=calc();
g[x]+=val;
}
++o;
}
}
int main(){
rd(n);
int rt=;
for(reg i=;i<=n;++i){
rd(fa[i][]);if(fa[i][]==) rt=i;
else add(fa[i][],i);
}
dfs(rt,);
for(reg j=;j<=;++j){
for(reg i=;i<=n;++i){
fa[i][j]=fa[fa[i][j-]][j-];
}
}
for(reg i=;i<=mx;++i){
for(solid x:mem[i]) g[x]=g[fa[x][]]+i-;
sol(mem[i]);
reverse(mem[i].begin(),mem[i].end());
sol(mem[i]);
}
prt(g,,n);
return ;
} }
signed main(){
Miracle::main();
return ;
} /*
Author: *Miracle*
*/

LCA和dfs本身着关系,

这里利用的本质上是,两个点的lca就是dfs栈不断回溯后,第一次前进下来的点就是lca(分叉地方)

O(1)LCA也是利用这个性质

CF860E Arkady and a Nobody-men的更多相关文章

  1. cf860E Arkady and A Nobody-men (树剖)

    容易得出,如果我们按照深度一层一层地做,做完一层后,这层某个点的答案就是它的祖先们的子树大小(统计大小时不包括树根) 由于我太菜了不会别的方法,虽然N是5e5的,还是只好用一个树剖(树状数组降常数)水 ...

  2. 一句话题解&&总结

    CF79D Password: 差分.两点取反,本质是匹配!最短路+状压DP 取反是套路,匹配是发现可以把操作进行目的化和阶段化,从而第二次转化问题. 且匹配不会影响别的位置答案 sequence 计 ...

  3. 【CF860E】Arkady and a Nobody-men 长链剖分

    [CF860E]Arkady and a Nobody-men 题意:给你一棵n个点的有根树.如果b是a的祖先,定义$r(a,b)$为b的子树中深度小于等于a的深度的点的个数(包括a).定义$z(a) ...

  4. Things about single men that women hate

    Things about single men that women hate为何你俘获不了女神的心?If you listen in to a group of single women talki ...

  5. Men and women can't be 'just friends

    Men and women can't be 'just friends' Can heterosexual men and women ever be "just friends" ...

  6. C. Greedy Arkady

    kk people want to split nn candies between them. Each candy should be given to exactly one of them o ...

  7. 广告狂人第一至七季/全集Mad Men迅雷下载

    广告狂人 第一季 Mad Men Season 1 (2007) 本季看点:你是谁?你想要什么?你爱乾什么?这些都不重要,重要的是你怎么把东西卖出去.凡是了解纽约的人都知道,今天,在麦迪逊大道(Mad ...

  8. 好汉两个半第十二季/全集Two and a Half Men迅雷下载

    本季Two And A Half Men Season 12 (2014)看点:<好汉两个半>的“半个”是因为第一季播出时杰克年纪太小,只能算半个.故事就在这三个主角和他们周围的女人中发生 ...

  9. 好汉两个半第一季/全集Two And A Half Men迅雷下载

    第一季 Two and a Half Men Season 1 (2003)看点:Charlie是一个潇洒自由的单身汉,但正面临离婚危机的兄弟Alan带着儿子Jake的突然来访完全打乱了Charlie ...

随机推荐

  1. 怎样写一个Hello World!

    Python 的 Hello, World! 应该是所有语言里面最简单的: print("Hello, World!")

  2. UVA Tress in a Wood

    https://vjudge.net/problem/UVA-10214 题意:给定一个坐标系.|x|<=a, |y|<=b 求坐标系中有多少点是可以从原点直接看到(即从原点和一个点连线, ...

  3. 工作单元 — Unit Of Work

    在进行数据库添加.修改.删除时,为了保证事务的一致性,即操作要么全部成功,要么全部失败.例如银行A.B两个账户的转账业务.一方失败都会导致事务的不完整性,从而事务回滚.而工作单元模式可以跟踪事务,在操 ...

  4. json字符转java bean忽略大小写

    使用objectMapper进行json字符的解析 com.fasterxml.jackson.databind.ObjectMapper ob =new com.fasterxml.jackson. ...

  5. Node.js学习(3)-用express改写留言本

    安装 cnpm i -S express cnpm i -S express-art-template cnpm i -S art-template   var express = require(' ...

  6. C++ STL 之 容器的深拷贝和浅拷贝

    如果我们没有提供拷贝构造函数,没有重载=操作符,vector 对我们的 mc 对象进行的简单的浅拷贝,将拷贝的对象插入到容器中,导致我们的 mc 对象的 data 指针和容器中mc 对象的拷贝对象中的 ...

  7. swagger 的使用

    最近在用 .Net Core 做项目 了解到swagger 是一个不错的工具 简单介绍一下 在使用asp.net core 进行api开发完成后,书写api说明文档对于程序员来说想必是件很痛苦的事情吧 ...

  8. Supervisor的使用

    版权声明:原创文章欢迎转载,不过要记得加出处哦 https://blog.csdn.net/wljk506/article/details/77146248 supervisord 是Linux/Un ...

  9. Image Processing and Computer Vision_Review:HPatches A benchmark and evaluation of handcrafted and learned local descriptors——2017.04

    翻译 HPatches:手工和学习本地描述符的基准和评估——http://tongtianta.site/paper/8979 摘要:在本文中,我们提出了一个评估本地图像描述符的新基准.我们证明现有数 ...

  10. 三次样条插值 cubic spline interpolation

    什么是三次样条插值 插值(interpolation)是在已知部分数据节点(knots)的情况下,求解经过这些已知点的曲线, 然后根据得到的曲线进行未知位置点函数值预测的方法(未知点在上述已知点自变量 ...