[JLOI2014]松鼠的新家
嘟嘟嘟
这还是一道树链剖分板子题呀!
从1到n - 1枚举a[i],每一次使节点a[i]到a[i + 1]的路径加1,但这样的话除a[1],每一个点都多加了一个1,所以输出答案的时候减1即可。
![](/assets/blank.gif)
![](/assets/blank.gif)
1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<cmath> 5 #include<cstring> 6 #include<cstdlib> 7 #include<cctype> 8 #include<stack> 9 #include<queue> 10 #include<vector> 11 using namespace std; 12 #define enter puts("") 13 #define space putchar(' ') 14 #define Mem(a) memset(a, 0, sizeof(a)) 15 typedef long long ll; 16 typedef double db; 17 const int INF = 0x3f3f3f3f; 18 const db eps =1e-8; 19 const int maxn = 3e5 + 5; 20 inline ll read() 21 { 22 ll ans = 0; 23 char ch = getchar(), last = ' '; 24 while(!isdigit(ch)) {last = ch; ch = getchar();} 25 while(isdigit(ch)) {ans = ans * 10 + ch - '0'; ch = getchar();} 26 if(last == '-') ans = -ans; 27 return ans; 28 } 29 inline void write(ll x) 30 { 31 if(x < 0) putchar('-'), x = -x; 32 if(x >= 10) write(x / 10); 33 putchar(x % 10 + '0'); 34 } 35 36 int n, a[maxn]; 37 vector<int> v[maxn]; 38 39 bool vis[maxn]; 40 int fa[maxn], dep[maxn], size[maxn], son[maxn]; 41 void dfs1(int now) 42 { 43 vis[now] = 1; size[now] = 1; 44 for(int i = 0; i < (int)v[now].size(); ++i) 45 { 46 if(!vis[v[now][i]]) 47 { 48 fa[v[now][i]] = now; 49 dep[v[now][i]] = dep[now] + 1; 50 dfs1(v[now][i]); 51 size[now] += size[v[now][i]]; 52 if(!son[now] || size[v[now][i]] > size[son[now]]) son[now] = v[now][i]; 53 } 54 } 55 } 56 int top[maxn], dfsx[maxn], pos[maxn], cnt = 0; 57 void dfs2(int now) 58 { 59 vis[now] = 1; 60 dfsx[now] = ++cnt; pos[cnt] = now; 61 if(son[now]) 62 { 63 top[son[now]] = top[now]; 64 dfs2(son[now]); 65 } 66 for(int i = 0; i < (int)v[now].size(); ++i) 67 { 68 if(!vis[v[now][i]] && v[now][i] != son[now]) 69 { 70 top[v[now][i]] = v[now][i]; 71 dfs2(v[now][i]); 72 } 73 } 74 } 75 76 int l[maxn << 2], r[maxn << 2]; 77 ll sum[maxn << 2], lazy[maxn << 2]; 78 void build(int L, int R, int now) 79 { 80 l[now] = L; r[now] = R; 81 if(L == R) return; 82 int mid = (L + R) >> 1; 83 build(L, mid, now << 1); 84 build(mid + 1, R, now << 1 | 1); 85 } 86 void pushdown(int now) 87 { 88 if(lazy[now]) 89 { 90 sum[now << 1] += (r[now << 1] - l[now << 1] + 1) * lazy[now]; 91 sum[now << 1 | 1] += (r[now << 1 | 1] - l[now << 1 | 1] + 1) * lazy[now]; 92 lazy[now << 1] += lazy[now]; 93 lazy[now << 1 | 1] += lazy[now]; 94 lazy[now] = 0; 95 } 96 } 97 void update(int L, int R, int now) 98 { 99 if(l[now] == L && r[now] == R) 100 { 101 sum[now] += r[now] - l[now] + 1; 102 lazy[now]++; return; 103 } 104 pushdown(now); 105 int mid = (l[now] + r[now]) >> 1; 106 if(R <= mid) update(L, R, now << 1); 107 else if(L > mid) update(L ,R, now << 1 | 1); 108 else {update(L, mid, now << 1); update(mid + 1, R, now << 1 | 1);} 109 sum[now] = sum[now << 1] + sum[now << 1 | 1]; 110 } 111 ll query(int id, int now) 112 { 113 if(l[now] == r[now]) return sum[now]; 114 pushdown(now); 115 int mid = (l[now] + r[now]) >> 1; 116 if(id <= mid) return query(id, now << 1); 117 else return query(id, now << 1 | 1); 118 } 119 120 void update2(int x, int y) 121 { 122 123 while(top[x] != top[y]) 124 { 125 if(dep[top[x]] < dep[top[y]]) swap(x, y); 126 update(dfsx[top[x]], dfsx[x], 1); 127 x = fa[top[x]]; 128 } 129 if(dfsx[x] > dfsx[y]) swap(x, y); 130 update(dfsx[x], dfsx[y], 1); 131 } 132 133 ll ans[maxn]; 134 135 int main() 136 { 137 n = read(); 138 for(int i = 1; i <= n; ++i) a[i] = read(); 139 for(int i = 1; i < n; ++i) 140 { 141 int x = read(), y = read(); 142 v[x].push_back(y); v[y].push_back(x); 143 } 144 dfs1(1); Mem(vis); dfs2(1); 145 build(1, cnt, 1); 146 for(int i = 1; i < n; ++i) update2(a[i], a[i + 1]); 147 for(int i = 1; i <= n; ++i) {write(query(dfsx[i], 1) - (a[1] == i ? 0 : 1)); enter;} 148 return 0; 149 }
View Code
转载于:https://www.cnblogs.com/mrclr/p/9493498.html
[JLOI2014]松鼠的新家相关推荐
- [Luogu 3258] JLOI2014 松鼠的新家
[Luogu 3258] JLOI2014 松鼠的新家 LCA + 树上差分. 我呢,因为是树剖求的 LCA,预处理了 DFN(DFS 序),于是简化成了序列差分. qwq不讲了不讲了,贴代码. #i ...
- P3258 [JLOI2014]松鼠的新家
文章目录 题意: 题解: 树上差分 代码: 树链剖分 代码: P3258 [JLOI2014]松鼠的新家 题意: n个点,n-1条边,给出每个点的拜访顺序,问每个点经过几次(最后一次移动不算拜访) 题 ...
- 洛谷 P3258 [JLOI2014]松鼠的新家 解题报告
P3258 [JLOI2014]松鼠的新家 题目描述 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他 ...
- 3631: [JLOI2014]松鼠的新家
3631: [JLOI2014]松鼠的新家 Time Limit: 10 Sec Memory Limit: 128 MB Submit: 707 Solved: 342 [Submit][Sta ...
- bzoj 3631: [JLOI2014]松鼠的新家(LCA+树上差分)
3631: [JLOI2014]松鼠的新家 Time Limit: 10 Sec Memory Limit: 128 MB Submit: 2059 Solved: 1030 [Submit][S ...
- 洛谷 P3258 [JLOI2014]松鼠的新家 树上差分
缘起 [1]中我们学习了树上差分,并且a了一个裸的点差分. 现在继续树上差分~ 洛谷 P3258 [JLOI2014]松鼠的新家 分析 题目描述 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房 ...
- P3258[JLOI2014]松鼠的新家(LCA 树上差分)
P3258 [JLOI2014]松鼠的新家 题目描述 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他 ...
- bzoj3631[JLOI2014]松鼠的新家
bzoj3631[JLOI2014]松鼠的新家 题意: 给个n点树,再给个节点的游览顺序,每经过一个节点(包括上一个游览的点到下一个游览的点路径上的点)就可以从这个节点拿走一个糖,问所有节点一开始要放 ...
- P3258 [JLOI2014] 松鼠的新家 题解
P3258 [JLOI2014] 松鼠的新家 题解 洛谷 P3258 题目 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有 nnn 个房间,并且有 nnn−1 根树枝连接,每个房间都可以相互到达,且 ...
- 【BZOJ 3631】 [JLOI2014]松鼠的新家
3631: [JLOI2014]松鼠的新家 Time Limit: 10 Sec Memory Limit: 128 MB Submit: 681 Solved: 329 [Submit][Statu ...
最新文章
- cisco switch
- 响应式注意要添加“视口”约束标记---viewport
- php 打印对象详细信息,php打印显示数组与对象的函数详解
- Swift基础语法: 30 - Swift的基类, 子类, 重写, 重写方法, 重写属性, 防止重写
- Atlas应用程序调试技巧
- 16.IDA-列出函数中存在的全部call(函数调用窗口,查看函数内调用了哪些call)
- 数据结构期末复习之散列表的查找
- 日常积累--javaweb
- 阶段3 1.Mybatis_08.动态SQL_01.mybatis中的动态sql语句-if标签
- CentOS7.3 本地环境安装
- stc流水灯c语言程序,求51单片机流水灯跑马灯程序设计 (STC89C52RC)??
- fl_chart的简单使用——BarChart
- 这一年很幸运,平平淡淡的|2021 年度总结
- 关于uniapp cheneckbox复选框不显示对号的问题
- thinkadmin 配置 iis 宝塔、护卫神、phpstudy伪静态设置
- 01- SA8155P QNX LA/LV 启动(01) - startup
- 5G/NR 频带详解
- [Unity热更新]tolua# LuaFramework(七):lua使用DOTween
- Intel中国建厂:中国自主处理器边缘化
- 程序员不得不学的操作系统知识(三)