BZOJ 3631 【JLOI2014】 松鼠的新家
Description
Input
Output
HINT
2<= n <=300000
这道题一看,这不是要求每次给树上的一条路径权值加一,最后询问每个点的权值。那么这就是树剖的板子题了,套个树状数组即可。
然而,由于这道题只在最后有一个询问操作,那么树链剖分未免有点大材小用了。我们可以维护一个数组$b$,每次给$b_i$加上$x$就表示给从$i$到根的路径上所有节点的权值都加上$x$。这样,我们只需在最后$dfs$一遍,把值自底往上加即可得到权值数组。这样的话,每次给路径$(u,v)$上的点全部加一对应需要改变$b$数组中四个值:$b_u+1$,$b_v+1$,$lca(u,v)-1$,$fa(lca(u,v))-1$即可。这样我们修改的复杂度就极大地降低了。
然后,我一开始写了一个倍增求$lca$,后来发现其他人都跑得比我快……自己想了想,还是决定写个$Tarjan$求$lca$算了,毕竟以前没有写过……后来发现这真的好写,不比倍增难写……
$Tarjan$求$lca$大概的思路就是在$dfs$的时候,维护一个并查集,对已经$dfs$完了的点在并查集中指向它的$father$,正在栈中的点指向它自己。这样的话,每到一个点$u$,我们可以扫一遍所有的$(u,v)$这种询问,如果$v$被访问过了,那么这个询问的答案就是并查集中$v$的树根。感觉这个自己$YY$一下不难证明,这里就不证明了。
下面贴代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
#define maxn 300010
#define maxm 600010 using namespace std;
typedef long long llg; struct data{
int u,v;
}s[maxm];
int head[maxn],next[maxm],to[maxm],tt;
int he[maxn],ne[maxm],t1[maxm],t2;
int n,ans[maxn],fa[maxn],a[maxn],ff[maxn],b[maxn]; int getint(){
int w=0;bool q=0;
char c=getchar();
while((c>'9'||c<'0')&&c!='-') c=getchar();
if(c=='-') c=getchar(),q=1;
while(c>='0'&&c<='9') w=w*10+c-'0',c=getchar();
return q?-w:w;
} int find(int x){return fa[fa[x]]==fa[x]?fa[x]:fa[x]=find(fa[x]);}
void lik(int x,int y){t1[++t2]=y;ne[t2]=he[x];he[x]=t2;}
void link(int x,int y){
to[++tt]=y;next[tt]=head[x];head[x]=tt;
to[++tt]=x;next[tt]=head[y];head[y]=tt;
} void dfs(int u,int f){
fa[u]=u; ff[u]=f;
for(int i=he[u],v;v=t1[i],i;i=ne[i])
if(fa[s[v].v]) ans[(v-1)%(n-1)+1]=find(s[v].v);
for(int i=head[u],v;v=to[i],i;i=next[i])
if(v!=f) dfs(v,u);
fa[u]=f;
} void dfs(int u){
for(int i=head[u],v;v=to[i],i;i=next[i])
if(v!=ff[u]) dfs(v),b[u]+=b[v];
} int main(){
File("a");
n=getint();
for(int i=1;i<=n;i++) a[i]=getint();
for(int i=1;i<n;i++){
s[i].u=s[i+n-1].v=a[i]; lik(s[i].u,i);
s[i].v=s[i+n-1].u=a[i+1]; lik(s[i].v,i+n-1);
}
for(int i=2;i<=n;i++) link(getint(),getint());
dfs(1,0);
for(int i=1;i<n;i++){
b[s[i].u]++; b[ff[s[i].v]]++;
b[ans[i]]--; b[ff[ans[i]]]--;
}
dfs(1);
for(int i=1;i<=n;i++) printf("%d\n",b[i]);
return 0;
}
BZOJ 3631 【JLOI2014】 松鼠的新家的更多相关文章
- BZOJ 3631: [JLOI2014]松鼠的新家( 树链剖分 )
裸树链剖分... ------------------------------------------------------------------- #include<bits/stdc++ ...
- Bzoj 3631: [JLOI2014]松鼠的新家(树链剖分+线段树)
3631: [JLOI2014]松鼠的新家 Time Limit: 10 Sec Memory Limit: 128 MB Description 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个 ...
- bzoj 3631: [JLOI2014]松鼠的新家
Description 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他居然真的住在"树&q ...
- 洛谷 P3258 BZOJ 3631 [JLOI2014]松鼠的新家
题目描述 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他居然真的住在”树“上. 松鼠想邀请小熊维尼前 ...
- BZOJ 3631: [JLOI2014]松鼠的新家 树上差分 + LCA
Description 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他居然真的住在“树”上.松鼠想邀 ...
- BZOJ.3631.[JLOI2014]松鼠的新家(树上差分)
题目链接 树剖/差分裸题.. //28260kb 584ms #include <cstdio> #include <cctype> #include <algorith ...
- 3631: [JLOI2014]松鼠的新家
3631: [JLOI2014]松鼠的新家 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 707 Solved: 342[Submit][Statu ...
- 3631. [JLOI2014]松鼠的新家【树形DP】
Description 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他居然真的住在“树”上.松鼠想邀 ...
- [Bzoj3631][JLOI2014]松鼠的新家 (树上前缀和)
3631: [JLOI2014]松鼠的新家 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2350 Solved: 1212[Submit][Sta ...
- [填坑]树上差分 例题:[JLOI2014]松鼠的新家(LCA)
今天算是把LCA这个坑填上了一点点,又复习(其实是预习)了一下树上差分.其实普通的差分我还是会的,树上的嘛,也是懂原理的就是没怎么打过. 我们先来把树上差分能做到的看一下: 1.找所有路径公共覆盖的边 ...
随机推荐
- linux下使用yum安装mysql详解
1.安装客户端和服务器端 确认mysql是否已安装: ? 1 2 yum list installed mysql* rpm -qa | grep mysql* 查看是否有安装包: ? 1 yum l ...
- 最近项目用到Dubbo框架,临时抱佛脚分享一下共探讨。
1. Dubbo是什么? Dubbo是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案.简单的说,dubbo就是个服务框架,如果没有分布式的需求,其实是不需 ...
- 项目管理之道--纪我的新书《PMP项目管理认证学习指南(第4版)》出版并预祝大卖!
新年伊始,我最新的项目管理书籍——<PMP项目管理认证学习指南(第4版)>也出版了,真是新年新气象啊!翻译英文书籍是一件任重道远的工作,除了要具备扎实的基本功,熟悉相关的领域外,还需要细致 ...
- Virtual Box 杂记
1. Virtual Box后台运行 a. VBoxManage startvm yourvmname --type headlessb. VBoxHeadless --startvm yourvmn ...
- mac版 android破解软件下载安装
1 apktool下载安装 下载地址https://code.google.com/p/android-apktool/ [1].下载apktool.jar — 解压 [2].下载Mac上的辅助工具a ...
- Mysql hql字符串字段中是否包含某个字符串,用 find_in_set
有这样一个需求,在Mysql数据库字符串字段(权限)中,有范围在 1 到 N 之间代表不同权限的值,分别被','分开,现在要取出具有某权限的所有成员列表. 创建表: 1 CREATE TABLE us ...
- Java for XML: JAXP、JAXB、JAXM、JAX-RPC、JAX-WS
在XML领域里,对XML文件的校验有两种方式:DTD校验.Schema校验.在Java中,对于XML的解析,有多种方式:DOM解析.SAX解析.StAX解析.结合XML和Java后,就产生了Bind技 ...
- 【SQL篇章】【SQL语句梳理 :--基于MySQL5.6】【已梳理:ALTER TABLE解析】
ALTER TABLE 解析实例: SQL: 1.增加列 2.增加列,调整列顺序 3.增加索引 4.增加约束 5.增加全文索引FULL-TEXT 6.改变列的默认值 7.改变列名字(类型,顺序) 8. ...
- PKG_COLLECTION_LHR 存储过程或函数返回集合类型
存储过程或函数可以返回集合类型,方法很多,今天整理在一个包中,其它情况可照猫画虎. CREATE OR REPLACE PACKAGE PKG_COLLECTION_LHR AUTHID CURREN ...
- 记一次使用openrowset 的坑
前几天被老大训斥连openrowset 都不会用,然后我就去看了文档,想测试一下栗子~ openrowset 的具体语法我就不贴了,戳这里:https://msdn.microsoft.com/zh- ...