BZOJ 3757: 苹果树
3757: 苹果树
Time Limit: 20 Sec Memory Limit: 256 MB
Submit: 1726 Solved: 550
[Submit][Status][Discuss]
Description
神犇家门口种了一棵苹果树。苹果树作为一棵树,当然是呈树状结构,每根树枝连接两个苹果,每个苹果都可以沿着一条由树枝构成的路径连到树根,而且这样的路径只存在一条。由于这棵苹果树是神犇种的,所以苹果都发生了变异,变成了各种各样的颜色。我们用一个到n之间的正整数来表示一种颜色。树上一共有n个苹果。每个苹果都被编了号码,号码为一个1到n之间的正整数。我们用0代表树根。只会有一个苹果直接根。
有许许多多的人来神犇家里膜拜神犇。可神犇可不是随便就能膜拜的。前来膜拜神犇的人需要正确回答一个问题,才能进屋膜拜神犇。这个问题就是,从树上编号为u的苹果出发,由树枝走到编号为v的苹果,路径上经过的苹果一共有多少种不同的颜色(包括苹果u和苹果v的颜色)?不过神犇注意到,有些来膜拜的人患有色盲症。具体地说,一个人可能会认为颜色a就是颜色b,那么他们在数苹果的颜色时,如果既出现了颜色a的苹果,又出现了颜色b的苹果,这个人只会算入颜色b,而不会把颜色a算进来。
神犇是一个好人,他不会强人所难,也就会接受由于色盲症导致的答案错误(当然答案在色盲环境下也必须是正确的)。不过这样神犇也就要更改他原先数颜色的程序了。虽然这对于神犇来说是小菜一碟,但是他想考验一下你。你能替神犇完成这项任务吗?
Input
Output
输出一共m行,每行仅包含一个整数,代表这个人应该数出的颜色种数。
Sample Input
1 1 3 3 2
0 1
1 2
1 3
2 4
3 5
1 4 0 0
1 4 1 3
1 4 1 2
Sample Output
1
2
HINT
Source
树上莫队的模板题。
仿照序列莫队的方式对树进行适当的sqrt(n)分块,然后按照区间左端点的所在块分组;每组内按照右端点的DFS序排序。易知两个组内询问转移答案时,左端点至多移动O(sqrt(n)),而右端点全局是O(n)的,复杂度O(Nsqrt(N))。至于维护哪些点以及如何转移,网上有很详细的解释。
#include <bits/stdc++.h>
inline int nextInt(void) {
register int ret = ;
register int neg = ;
register int bit = getchar();
while (bit < '') {
if (bit == '-')
neg ^= ;
bit = getchar();
}
while (bit >= '') {
ret = ret* + bit - '';
bit = getchar();
}
return neg ? -ret : ret;
}
const int siz = ;
int n, m, s, col[siz], ans[siz];
int hd[siz], nt[siz], to[siz], tot;
int fa[siz][], dp[siz], dn[siz], tim;
int sz[siz], bl[siz], cnt, vs[siz], ct[siz], sum;
void dfs(int u, int f) {
fa[u][] = f;
dn[u] = ++tim;
dp[u] = dp[f] + ;
for (int i = ; i < ; ++i)
fa[u][i] = fa[fa[u][i - ]][i - ];
for (int i = hd[u]; i; i = nt[i])if (to[i] != f) {
if (sz[bl[u]] < s)
++sz[bl[to[i]] = bl[u]];
else
++sz[bl[to[i]] = ++cnt];
dfs(to[i], u);
}
}
inline int lca(int a, int b) {
if (dp[a] < dp[b])std::swap(a, b);
for (int i = ; ~i; --i)
if (dp[fa[a][i]] >= dp[b])
a = fa[a][i];
if (a == b)return a;
for (int i = ; ~i; --i)
if (fa[a][i] != fa[b][i])
a = fa[a][i], b = fa[b][i];
return fa[a][];
}
struct query {
int l, r, a, b, id;
void read(int i) {
id = i;
l = nextInt();
r = nextInt();
a = nextInt();
b = nextInt();
if (dn[l] > dn[r])
std::swap(l, r);
}
}qry[siz];
inline bool cmp_query(const query &A, const query &B) {
if (bl[A.l] != bl[B.l])
return bl[A.l] < bl[B.l];
else
return dn[A.r] < dn[B.r];
}
inline void change(int t) {
vs[t] ^= ;
if (vs[t])
sum += (++ct[col[t]] == );
else
sum -= (--ct[col[t]] == );
}
inline void change(int a, int b) {
int L = lca(a, b);
while (a != L)
change(a), a = fa[a][];
while (b != L)
change(b), b = fa[b][];
}
int L, R, LCA; // Path(L,R) ^ LCA
inline void solve(const query &q) {
change(L, q.l); L = q.l;
change(R, q.r); R = q.r;
LCA = lca(L, R);
change(LCA);
ans[q.id] = sum;
if (q.a != q.b)
if (ct[q.a] && ct[q.b])
--ans[q.id];
change(LCA);
}
signed main(void) {
// freopen("apple.in", "r", stdin);
// freopen("apple.out", "w", stdout);
n = nextInt();
m = nextInt();
for (int i = ; i <= n; ++i)
col[i] = nextInt();
for (int i = ; i <= n; ++i) {
int x = nextInt();
int y = nextInt();
nt[++tot] = hd[x]; to[tot] = y; hd[x] = tot;
nt[++tot] = hd[y]; to[tot] = x; hd[y] = tot;
}
L = R = to[hd[]]; s = sqrt(n);
sz[bl[] = cnt = ] = ; dfs(, );
for (int i = ; i <= m; ++i)qry[i].read(i);
std::sort(qry + , qry + + m, cmp_query);
for (int i = ; i <= m; ++i)solve(qry[i]);
for (int i = ; i <= m; ++i)printf("%d\n", ans[i]);
}
因为BZOJ上已经不再提供测试,submit之后也只能得到RE的结果,只好自己造几个数据,就当AC了。
@Author: YouSiki
BZOJ 3757: 苹果树的更多相关文章
- bzoj 3757 苹果树(树上莫队算法)
[题意] 有若干个询问,询问路径u,v上的颜色总数,另外有要求a,b,意为将a颜色看作b颜色. [思路] vfk真是神系列233. Quote: 用S(v, u)代表 v到u的路径上的结点的集合. 用 ...
- BZOJ.3757.苹果树(树上莫队)
题面链接 /* 代码正确性不保证..(不过交了SPOJ没WA T了最后一个点) 在DFS序做莫队 当一个点不是另一个点的LCA时,需要加上它们LCA的贡献 */ #include <cmath& ...
- BZOJ 3757 苹果树 ——莫队算法
挺好的一道题目,怎么就没有版权了呢?大数据拍过了,精神AC.... 发现几种颜色这性质比较垃圾,不可加,莫队硬上. %了一发popoqqq大神的博客, 看了一波VFK关于糖果公园的博客, 又找了wjm ...
- 【BZOJ】3757: 苹果树
http://www.lydsy.com/JudgeOnline/problem.php?id=3757 题意:n个节点的树,每个点有一种颜色.现有m种询问,每次询问x y a b表示x到y的路径上颜 ...
- bzoj 3757 树上莫队
感谢以下文章作者: http://blog.csdn.net/kuribohg/article/details/41458639 http://vfleaking.blog.163.com/blog/ ...
- BZOJ - 3757 树上莫队解决离线路径问题 & 学习心得
题意:给你一棵树,求u,v最短路径的XXX(本题是统计权值种类) 今天课上摸鱼学了一种有意思的处理路径方式(其实是链式块状树翻车了看别的),据说实际运行跑的比XX记者还快 大概就是像序列莫队那样 首先 ...
- 【BZOJ】【3757】苹果树
树分块 orz HZWER http://hzwer.com/5259.html 不知为何我原本写的倍增求LCA给WA了……学习了HZWER的倍增新姿势- 树上分块的转移看vfk博客的讲解吧……(其实 ...
- 【BZOJ】3052: [wc2013]糖果公园
http://www.lydsy.com/JudgeOnline/problem.php?id=3052 题意:n个带颜色的点(m种),q次询问,每次询问x到y的路径上sum{w[次数]*v[颜色]} ...
- 【BZOJ-3757】苹果树 块状树 + 树上莫队
3757: 苹果树 Time Limit: 20 Sec Memory Limit: 256 MBSubmit: 1305 Solved: 503[Submit][Status][Discuss] ...
随机推荐
- iOS流行的开源代码库
本文介绍一些流行的iOS的开源代码库 1.AFNetworking 更新频率高的轻量级的第三方网络库,基于NSURL和NSOperation,支持iOS和OSX.https://github.com/ ...
- OC #import和@class的用法和区别
OC #import和@class的用法和区别 import会包含这个类的所有信息,包括实体变量和方法,而@class只是告诉编译器,其后面声明的名称是类的名称,至于这些类是如何定义的,暂时不用考虑, ...
- OC 协议
OC 协议 概念:定义了一个接口,其他类负责来实现这些接口.如果你的类实现了一个协议的方法时,则说该类遵循此协议. 非正式协议:非正式协议虽名为协议,但实际上是挂于NSObject上的未实现分类(Un ...
- rails程序文件名命名规范
1 一般文件名是用小写单词加下划线分割,但类的名字用骆驼法.例如 sessions_controller.rb中定义SessionsController. 2 helpers内的文件为辅助类,定义了许 ...
- 新书出版《.NET框架设计—模式、配置、工具》感恩回馈社区!
很高兴我的第一本书由图灵出版社出版.本书总结了我这些年来对框架学习.研究的总结,里面纯干货,无半句废话. 书的详情请看互动网的销售页面:http://product.china-pub.com/377 ...
- 基于php基础语言编写的小程序之计算器
基于php基础语言编写的小程序之计算器 需求:在输入框中输入数字进行加.减.乘.除运算(html+php) 思路: 1首先要创建输入数字和运算符的输入框,数字用input的text属性,运算符用sel ...
- 分布式搜索引擎Elasticsearch的查询与过滤
一.写入 先来一个简单的官方例子,插入的参数为-XPUT,插入一条记录. curl -XPUT 'http://localhost:9200/test/users/1' -d '{ "use ...
- SQL Like模糊查询一些小知识
模糊查询: where mc like '值':返回值等同于where mc ='值' where mc like '%值':匹配 名称是 '*值'(以“值”作为结尾)的所有数据,*表示任何值任何长度 ...
- Windows下Apache + PHP SESSION丢失的惨痛经历
今天的工作是迁移一个PHP站点至新服务器. 创建一台Windows Server 2008虚拟机,并在其上停掉net stop http服务(避免争抢80端口),安装配置 Apache + PHP,迁 ...
- 创建 Image - 每天5分钟玩转 OpenStack(21)
本节演示如何通过 Web GUI 和 CLI 两种方法创建 Image. OpenStack 为终端用户提供了 Web UI(Horizon)和命令行 CLI 两种交换界面.两种方式我们都要会用. 可 ...