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. Python中的math常用方法总结(转)http://www.cnblogs.com/renpingsheng/p/7171950.html

    python中math模块常用的方法整理   ceil:取大于等于x的最小的整数值,如果x是一个整数,则返回x copysign:把y的正负号加到x前面,可以使用0 cos:求x的余弦,x必须是弧度 ...

  2. C# Extension Methods(C#类方法扩展)

    使用Extension methods 可以在已有的类型(types)中添加方法(Methods),而无需通过增加一种新的类型或修改已有的类型. 比如说,想要给string类型增加一个PrintStr ...

  3. DSN 建立达梦7(DM)连接

    (DSN)Data Source Name 数据源名称 “ODBC数据源管理器”提供了三种DSN,分别为用户DSN.系统DSN和文件DSN.其中:      用户DSN会把相应的配置信息保存在Wind ...

  4. 一个下午整理的Web前端常见的英文缩写

    PV (Page View)页面浏览量 FED(Front-End Development)前端开发 F2E(Front-End Engineer)前端工程师 WWW(World Wide Web)万 ...

  5. js同步和异步

    JavaScript语言的一大特点就是单线程,也就是说,同一个时间只能做一件事. JavaScript的单线程,与它的用途有关.作为浏览器脚本语言,JavaScript的主要用途是与用户互动,以及操作 ...

  6. Lab2 Report

    1.安装SeleniumIDE插件 a)安装Firefox 17.0 - 56.*版本的firefox,下载地址为:http://ftp.mozilla.org/pub/firefox/release ...

  7. Delphi 抽象方法

  8. web开发:javascript操作

    一.函数闭包 二.面向对象 三.js选择器 四.事件初始 五.js处理页面内容 六.js事件控制标题栏 七.js控制类名 一.函数闭包 ```js// 函数的嵌套定义, 定义在内部的函数就称之为 闭包 ...

  9. Hadoop_20_MapReduce程序的运行模式

    1.MapReduce程序的运行模式 1. Windows中运行MapReduce程序 (1)mapreduce程序是被提交给LocalJobRunner在本地以单进程的形式运行 (2)而处理的数据及 ...

  10. ubuntu系统---切换Py2.X与Py3.X版本

    ubuntu系统---切换Python2.X与Python3.X版本 Python3.X将成为以后的趋势,Python2.X当前用的稍多的版本,但现在不再更新了.因此,小主电脑里也安装了好两个版本的p ...