树链剖分 [JLOI2014]松鼠的新家
[JLOI2014]松鼠的新家
时间限制: 1 Sec 内存限制: 128 MB
题目描述
输入
输出
样例输入
5
1 4 5 3 2
1 2
2 4
2 3
4 5
样例输出
1
2
1
2
1
提示
2<= n <=300000
树链剖分裸题,全当复习了。
首先既然是在树上,那么两点之间的路径就是唯一的了,果断树剖,其实LCA也可以,不过时间复杂度貌似并不允许,所以放弃。
首先,可以明确的是,我们直接从a[1]点位出发一定是最优的,不知道Q某犇为啥会纠结这个,然后就是慢慢慢慢的树剖了,然后就是一两个坑点,首先,虽然每一次树剖都是从a[i]~a[i+1],但a[i]早在求a[i-1]~a[i]时算过了,所以当我们最后输出的时候一定要记得把a[2~n]的结果-1。为什么要把a[n]的结果也减一呢?读题,a[n]是餐厅,因此不必放糖,但这并不意味着来回经过不必放糖,所以在最后一起减掉就好了。
#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#include<queue>
#include<string>
#include<cmath>
# define N
using namespace std;
int n;
int b[],a[];
struct ro{
int to;
int next;
}road[];
int zz;
void build(int x,int y){
zz++;
road[zz].to=y;
road[zz].next=a[x];
a[x]=zz;
}
int deep[N],fa[N],hson[N],size[N];
void dfs(int x,int dep){
deep[x]=dep;
size[x]=;
for(int i=a[x];i>;i=road[i].next)
{
int y=road[i].to;
if(fa[x]==y)continue;
fa[y]=x;
dfs(y,dep+);
size[x]+=size[y];
if(size[hson[x]]<size[y])
hson[x]=y;
}
}
int zz2;
int f2[N],dl[N],dfn[N];
void dfs2(int x,int top){
f2[x]=top;
zz2++;
dl[zz2]=x;
dfn[x]=zz2;
if(hson[x]) dfs2(hson[x],top);
for(int i=a[x];i>;i=road[i].next)
{
int y=road[i].to;
if(y==fa[x]||y==hson[x]) continue;
dfs2(y,y);
}
}
struct no{
int sum;
int lazy;
int right,left;
int mid;
}node[*N];
void build(int left,int right,int x){
node[x].left=left;
node[x].right=right;
if(left==right)
{
return;
}
int mid=(left+right)/;
node[x].mid=mid;
build(left,mid,*x);
build(mid+,right,*x+);
}
void pushdown(int x){
if(node[x].lazy)
{
node[*x].lazy+=node[x].lazy;
node[*x+].lazy+=node[x].lazy;
node[x*].sum+=node[x].lazy;
node[*x+].sum+=node[x].lazy;
node[x].lazy=;
}
}
void add(int left,int right,int x){
if(node[x].left==left&&node[x].right==right)
{
node[x].sum++;
node[x].lazy++;
return;
}
pushdown(x);
int mid=node[x].mid;
if(right<=mid)
{
add(left,right,*x);
}
else if(mid<left)
{
add(left,right,*x+);
}
else
{
add(left,mid,*x);
add(mid+,right,*x+);
}
node[x].sum=node[x*].sum+node[*x+].sum;
}
int get(int left,int right,int x)
{
if(node[x].left==node[x].right)
{
return node[x].sum;
}
pushdown(x);
int mid=node[x].mid;
if(left<=mid)
return get(left,right,*x);
else
return get(left,right,*x+);
}
void change(int x,int y){ int fx=f2[x],fy=f2[y];
while(fx!=fy)
{
if(deep[fx]<deep[fy])
{
swap(fx,fy);
swap(x,y);
}
add(dfn[fx],dfn[x],);
x=fa[fx];
fx=f2[x];
} if(deep[y]<deep[x]) swap(y,x);
if(dfn[x]<=dfn[y])
add(dfn[x],dfn[y],); }
int main(){
scanf("%d",&n);
for(int i=;i<=n;i++)
scanf("%d",&b[i]);
for(int i=;i<n;i++)
{
int x,y;
scanf("%d%d",&x,&y);
build(x,y);
build(y,x);
}
dfs(,);
dfs2(,);
build(,n,);
for(int i=;i<=n;i++)
{
change(b[i-],b[i]);
}
for(int i=;i<=n;i++)
{
//cout<<endl;
int x=get(dfn[i],dfn[i],);
if(i!=b[])
x--;
printf("%d\n",x);
}
//while(1);
return ;
}
树链剖分 [JLOI2014]松鼠的新家的更多相关文章
- 【树链剖分】【树状数组】【最近公共祖先】【块状树】bzoj3631 [JLOI2014]松鼠的新家
裸题,树状数组区间修改+单点查询.当然要稍微讨论一下链的左右端点是否修改的情况咯. #include<cstdio> #include<algorithm> #include& ...
- BZOJ 3631: [JLOI2014]松鼠的新家( 树链剖分 )
裸树链剖分... ------------------------------------------------------------------- #include<bits/stdc++ ...
- [JLOI2014]松鼠的新家(树链剖分)
[JLOI2014]松鼠的新家(luogu) Description 题目描述 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间 ...
- Bzoj 3631: [JLOI2014]松鼠的新家(树链剖分+线段树)
3631: [JLOI2014]松鼠的新家 Time Limit: 10 Sec Memory Limit: 128 MB Description 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个 ...
- 洛谷 P3258 [JLOI2014]松鼠的新家 树链剖分+差分前缀和优化
目录 题面 题目链接 题目描述 输入输出格式 输入格式 输出格式 输入输出样例 输入样例: 输出样例: 说明 说明 思路 AC代码 优化 优化后AC代码 总结 题面 题目链接 P3258 [JLOI2 ...
- [JLOI2014]松鼠的新家 (树剖)
题目 P3258 [JLOI2014]松鼠的新家 解析 非常裸的一道树剖题 链上修改+单点查询的板子 记录一下所经过的点\(now[i]\),每次更新\(now[i-1]到now[i]\) 我们链上更 ...
- 3631: [JLOI2014]松鼠的新家
3631: [JLOI2014]松鼠的新家 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 707 Solved: 342[Submit][Statu ...
- 洛谷 P3258 [JLOI2014]松鼠的新家 解题报告
P3258 [JLOI2014]松鼠的新家 题目描述 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他 ...
- 洛谷 P3258 [JLOI2014]松鼠的新家 题解
P3258 [JLOI2014]松鼠的新家 题目描述 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他 ...
随机推荐
- Ruby已经慢慢走向衰退了,那些年代久远而且小众的语言没有翻身的可能性
Ruby已经慢慢走向衰退了,现在WEB开发里,NODE.JS+前端各种框架是主流,PHP.ruby.Asp.net.python等语言在网站编程方面只会越来越少.数据领域方面,机器学习和人工智能中,p ...
- Linux SD卡建立两个分区
本文主要介绍Linux 环境下 SD 卡建立两个分区的操作流程: 操作环境:Linux Ubuntu 2016.4 操作目的:将 SD 卡分为两个分区:第一分区格式为 FAT32,大小 500M.第二 ...
- Elasticsearch教程(一)简介与安装
简单概念 ElasticSearch是一个基于Lucene的搜索服务器.它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口.Elasticsearch是用Java开发的,并作为 ...
- Windows 各种计时函数总结(QueryPerformanceCounter可以达到微秒)
本文对Windows平台下常用的计时函数进行总结,包括精度为秒.毫秒.微秒三种精度的5种方法.分为在标准C/C++下的二种time()及clock(),标准C/C++所以使用的time()及clock ...
- delphi LPT1端口打印与开钱箱
{设置打印机}Assignfile(RPrinter,'LPT1'); {准备写文件}Rewrite(RPrinter); {向后倒纸}//Writeln(RPrinter,chr($b)+chr(2 ...
- postgres数据库小记
因为工作中需要查询其他部门数据库,刚好是postgres数据库,用python链接的话,可以用psycopg2库,具体用法其实和MysqlDB是一样的,就是安装的时候遇到点问题. 安装的时候,提示: ...
- shell多线程之进程间通信
# 这是一个简单的并发程序,有如下要求: # .有两个程序a和b,希望他们能并发执行,以节约时间 # .a和b都是按照日期顺序执行,但b每日程序的前提条件是当日a的程序已经执行完毕 #解决方案: # ...
- 使用fastjson读取超巨json文件引起的GC问题
项目中需要将巨量数据生成的json文件解析,并写入数据库,使用了 alibaba 的 fastjson,在实践过程中遇到了 GC 问题,记录如下: 数据大约为70万条,文件大小在3~4G左右,使用 f ...
- c++汉诺塔相关知识总结1
困扰已久,难以攻克的汉诺塔总结来啦 Part One 汉诺塔到底是什么呢? 汉诺塔(Tower of Hanoi)源于印度传说中,大梵天创造世界时造了三根金钢石柱子,其中一根柱子自底向上叠着64片黄金 ...
- JavaScript 一元正号运算符
本文适合JavaScript初学者. 一元正号介绍 一元正号运算符(+)位于其操作数前面,计算其操作数的数值,如果操作数不是一个数值,会尝试将其转换成一个数值. 尽管一元负号也能转换非数值类型,但是一 ...