BZOJ3631 [JLOI2014] 松鼠的新家
2015-12-20 16:06
295 查看
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3631
可是这样会导致维尼重复走很多房间,懒惰的维尼不听地推辞。可是松鼠告诉他,每走到一个房间,他就可以从房间拿一块糖果吃。维尼是个馋家伙,立马就答应了。
现在松鼠希望知道为了保证维尼有糖果吃,他需要在每一个房间各放至少多少个糖果。因为松鼠参观指南上的最后一个房间an是餐厅,餐厅里他准备了丰盛的大餐,所以当维尼在参观的最后到达餐厅时就不需要再拿糖果吃了。
第二行n个整数,依次描述a1-an
接下来n-1行,每行两个整数x,y,表示标号x和y的两个房间之间有树枝相连。
以前第一次看到认为是倍增,现在一眼扫过去裸链剖……我还是Too young, too simple, sometimes naive.
这道题要求对每一个节点都输出答案,实测对整棵树自上而下递归一次记录每个节点的答案,比用普通线段树通用的询问方法能快300ms左右。
对于某个节点,如果它不是起点则要将答案减1(因为有重复计算)。
View Code
Description
松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的。天哪,他居然真的住在“树”上。松鼠想邀请小熊维尼前来参观,并且还指定一份参观指南,他希望维尼能够按照他的指南顺序,先去a1,再去a2,……,最后到an,去参观新家。可是这样会导致维尼重复走很多房间,懒惰的维尼不听地推辞。可是松鼠告诉他,每走到一个房间,他就可以从房间拿一块糖果吃。维尼是个馋家伙,立马就答应了。
现在松鼠希望知道为了保证维尼有糖果吃,他需要在每一个房间各放至少多少个糖果。因为松鼠参观指南上的最后一个房间an是餐厅,餐厅里他准备了丰盛的大餐,所以当维尼在参观的最后到达餐厅时就不需要再拿糖果吃了。
Input
第一行一个整数n,表示房间个数第二行n个整数,依次描述a1-an
接下来n-1行,每行两个整数x,y,表示标号x和y的两个房间之间有树枝相连。
Output
一共n行,第i行输出标号为i的房间至少需要放多少个糖果,才能让维尼有糖果吃。以前第一次看到认为是倍增,现在一眼扫过去裸链剖……我还是Too young, too simple, sometimes naive.
这道题要求对每一个节点都输出答案,实测对整棵树自上而下递归一次记录每个节点的答案,比用普通线段树通用的询问方法能快300ms左右。
对于某个节点,如果它不是起点则要将答案减1(因为有重复计算)。
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #define rep(i,l,r) for(int i=l; i<=r; i++) #define clr(x,y) memset(x,y,sizeof(x)) #define travel(x) for(Edge *p=last[x]; p; p=p->pre) using namespace std; const int maxn = 300010; struct Edge{ Edge *pre; int to; }edge[maxn<<1]; Edge *last[maxn],*pt; struct node{ int l,r,v,t; }t[maxn<<2]; int n,x,y,segnum=0,a[maxn],depth[maxn],fa[maxn],size[maxn],pos[maxn],belong[maxn],ans[maxn]; bool vis[maxn]; inline int read(){ int ans = 0, f = 1; char c = getchar(); while (!isdigit(c)){ if (c == '-') f = -1; c = getchar(); } while (isdigit(c)){ ans = ans * 10 + c - '0'; c = getchar(); } return ans * f; } inline void addedge(int x,int y){ pt->pre = last[x]; pt->to = y; last[x] = pt++; } void dfs1(int x){ vis[x] = 1; size[x] = 1; travel(x){ if (vis[p->to]) continue; depth[p->to] = depth[x] + 1; fa[p->to] = x; dfs1(p->to); size[x] += size[p->to]; } } void dfs2(int x,int chain){ int k = 0; pos[x] = ++segnum; belong[x] = chain; travel(x){ if (depth[p->to] == depth[x] + 1 && size[p->to] > size[k]) k = p->to; } if (!k) return; dfs2(k,chain); travel(x){ if (p->to != k && depth[p->to] > depth[x]) dfs2(p->to,p->to); } } inline void pushdown(int w){ if ((!t[w].t) || t[w].l == t[w].r) return; t[w<<1].t += t[w].t; t[w<<1|1].t += t[w].t; t[w<<1].v += (t[w<<1].r - t[w<<1].l + 1) * t[w].t; t[w<<1|1].v += (t[w<<1|1].r - t[w<<1|1].l + 1) * t[w].t; t[w].t = 0; } inline void maintain(int w){ t[w].v = t[w<<1].v + t[w<<1|1].v; } void build(int u,int v,int w){ t[w].l = u; t[w].r = v; t[w].v = t[w].t = 0; if (u == v) return; int mid = (u + v) >> 1; build(u,mid,w<<1); build(mid+1,v,w<<1|1); } void change(int u,int v,int w){ pushdown(w); if (u == t[w].l && v == t[w].r){ t[w].v += v - u + 1; t[w].t += 1; return; } int mid = (t[w].l + t[w].r) >> 1; if (v <= mid) change(u,v,w<<1); else if (u > mid) change(u,v,w<<1|1); else{ change(u,mid,w<<1); change(mid+1,v,w<<1|1); } maintain(w); } void getans(int u,int v,int w){ pushdown(w); if (u == v){ ans[u] = t[w].v; return; } int mid = (u + v) >> 1; getans(u,mid,w<<1); getans(mid+1,v,w<<1|1); } void modify(int x,int y){ while (belong[x] != belong[y]){ if (depth[belong[x]] < depth[belong[y]]) swap(x,y); change(pos[belong[x]],pos[x],1); x = fa[belong[x]]; } if (depth[x] < depth[y]) swap(x,y); change(pos[y],pos[x],1); } int main(){ n = read(); rep(i,1,n) a[i] = read(); clr(last,0); pt = edge; rep(i,1,n-1){ x = read(); y = read(); addedge(x,y); addedge(y,x); } clr(vis,0); depth[1] = 1; dfs1(1); dfs2(1,1); build(1,n,1); rep(i,2,n) modify(a[i],a[i-1]); getans(1,n,1); rep(i,1,n){ printf("%d\n",i == a[1] ? ans[pos[i]] : ans[pos[i]] - 1); } return 0; }
View Code
相关文章推荐
- 如何在React中使用CSS3动画
- 软件工程实践总结
- SyntaxHighlighter去掉右上角帮助图标的正确方法
- 数据结构小结(六)树
- 100个高质量Java开发者博客(20151220更新)
- [从头学数学] 第09节 20以内的进位加法
- leetcode刷题日记——Two Sum
- HTML 5提供的一些新的标签用法以及和HTML 4的区别
- 向linux内核加入系统调用新老内核比較
- 《iOS Human Interface Guidelines》——Apple Pay
- $'\t' 解释
- 关于java.lang.NoClassDefFoundError: com/sun/mail/util/LineInputStream解决办法
- ArcGIS 创建要素时提示“表已经被注册(table already registered)”
- 让正常网页呈现黑白色调的方法
- LBS的定位API
- Html5新标签解释及用法
- 安卓UI之安卓icon大小
- netfilter/iptables全攻略
- C#——重写与抽象类
- scala-39:ListBuffer、ArrayBuffer、Queue、Stack操作代码实战