bzoj2589【 Spoj 10707】 Count on a tree II

题目描述

给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v),你需要回答u xor lastans和v这两个节点间有多少种不同的点权。其中lastans是上一个询问的答案,初始为0,即第一个询问的u是明文。

输入格式

第一行两个整数N,M。
第二行有N个整数,其中第i个整数表示点i的权值。
后面N-1行每行两个整数(x,y),表示点x到点y有一条边。
最后M行每行两个整数(u,v),表示一组询问。
数据范围是N<=40000 M<=100000 点权在int范围内 

输出格式

M行,表示每个询问的答案。
  • 题解

    • 树上莫队;
    • 如果不要求强制在线的话比较传统;
    • 强制在线有点麻烦:
    • 对树按深度分块,当一个点向下的深度超过$\sqrt{N}$就分一块;
    • 这样分块保证了深度和块的数量在$O(\sqrt{N})$内;
    • 预处理每个块的根对其他所有点的答案,这时$O(n\sqrt{N})$的时间和空间的;
    • 考虑一个询问$u,v$如果在同一个块里则暴力查询;$O(\sqrt{N})$
    • 否则假设$u$的根比$v$的根要深,否则交换;
    • 利用预处理得到$(root_{u},v)$的答案$O(1)$,暴力枚举$(u,root_{u})$的颜色$O(\sqrt{N})$;
    • 可持久化块状链表记录$u$到链上的每个颜色出现的最大深度;$O(\sqrt{N})$
    • 枚举的颜色没有出现过那么查询的最大深度一定小于$lca$的深度;

猜你喜欢

转载自www.cnblogs.com/Paul-Guderian/p/10344024.html