SPOJcot2 Count on a tree II (树上莫队)
You are given a tree with N nodes. The tree nodes are numbered from 1 to N. Each node has an integer weight.
We will ask you to perform the following operation:
- u v : ask for how many different integers that represent the weight of nodes there are on the path from u to v.
Input
In the first line there are two integers N and M. (N <= 40000, M <= 100000)
In the second line there are N integers. The i-th integer denotes the weight of the i-th node.
In the next N-1 lines, each line contains two integers u v, which describes an edge (u, v).
In the next M lines, each line contains two integers u v, which means an operation asking for how many different integers that represent the weight of nodes there are on the path from u to v.
Output
For each operation, print its result.
Example
Input:
8 2
105 2 9 3 8 5 7 7
1 2
1 3
1 4
3 5
3 6
3 7
4 8
2 5
7 8
Output:
4
4
题意:求两点间点权值的种类数量。
之前讲过了如何“皇室联邦分块”,由于此题没有要求在线,就先分块,然后莫队就行了。
每次转移的时候怕出错,就干脆vis标记即可。
此题还有很多在线的做法。强得不行。。。ORZ
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=;
const int maxm=;
int n,m,group[maxn]; struct in
{
int x; int y; int id;
friend bool operator< (in a,in b)
{
return group[a.x]!=group[b.x]?group[a.x]<group[b.x]:group[a.y]<group[b.y];
}
}q[maxm]; struct Solve
{
int maxi;
int Next[maxn<<],Laxt[maxn],To[maxn<<],cnt,delta;
int num[maxn],dep[maxn],anc[maxn][],w[maxn],wx[maxn];
int B,stc[maxn],top,tot,ans[maxm],vis[maxn]; int swap(int &u,int &v) { u^=v;v^=u;u^=v;}
int read()
{
int res=;bool t=false; char c=getchar();
while(c>''||c<'') { if(c=='-') t=true; c=getchar();}
while(c<=''&&c>='') { res=(res<<)+(res<<)+c-'';c=getchar();}
if(t) return -res; return res;
} void add(int u,int v)
{
Next[++cnt]=Laxt[u];
Laxt[u]=cnt; To[cnt]=v;
} void init()
{
int u,v; B=sqrt(n);
for(int i=;(<<i)<=n;i++) maxi=i;
for(int i=;i<=n;i++) scanf("%d",&w[i]);
for(int i=;i<=n;i++) wx[i]=w[i];
sort(wx+,wx+n+);
int tt=unique(wx+,wx+n+)-(wx+);
for(int i=;i<=n;i++)
w[i]=lower_bound(wx+,wx+tt+,w[i])-wx;
for(int i=;i<n;i++){
scanf("%d%d",&u,&v);
add(u,v); add(v,u);
}
dep[]=; dfs();
while(top) group[stc[top--]]=tot;//最后剩余部分莫忘liao。
for(int i=;i<=m;i++) {
q[i].id=i, scanf("%d%d",&q[i].x,&q[i].y);
if(group[q[i].x]<group[q[i].y]) swap(q[i].x,q[i].y);//稍微调整一下,可能会优化。
}
sort(q+,q+m+); get_LCA();
} void dfs(int u)
{
int Now=top;
for(int i=Laxt[u];i;i=Next[i])
if(!dep[To[i]]){
anc[To[i]][]=u; dep[To[i]]=dep[u]+; dfs(To[i]);
if(top-Now>=B) {
++tot; while(top!=Now) group[stc[top--]]=tot;
}
}
stc[++top]=u;
} void get_LCA()
{
for(int i=;i<=maxi;i++)
for(int j=;j<=n;j++)
anc[j][i]=anc[anc[j][i-]][i-];
} int LCA(int u,int v)
{
if(dep[u]<dep[v]) swap(u,v);
for(int i=maxi;i>=;i--)
if(dep[anc[u][i]]>=dep[v]) u=anc[u][i];
if(u==v) return u;
for(int i=maxi;i>=;i--){
if(anc[u][i]!=anc[v][i]){
u=anc[u][i];
v=anc[v][i];
}
} return anc[u][];
} void trans(int &u)
{
if(vis[u]) //已被记录,则本次去掉此点
{
if(--num[w[u]] == ) delta--;
}
else if(++num[w[u]] == ) delta++;
vis[u] ^= ;
u=anc[u][];
} void solve()
{
int su=,sv=; delta=;
for(int i = ; i <= m; i++)
{
int tu=q[i].x,tv=q[i].y;
int lca=LCA(su, tu);//两点朝lca移动,处理路径上的点
while(su!=lca) trans(su);
while(tu!=lca) trans(tu);
lca=LCA(sv,tv);
while(sv!=lca) trans(sv);
while(tv!=lca) trans(tv);
su=q[i].x,sv=q[i].y;
lca=LCA(sv, su);
ans[q[i].id]=delta+(!num[w[lca]]);//对lca特殊处理
}
for(int i=;i<=m;i++) printf("%d\n",ans[i]);
}
}Tree;
int main()
{
scanf("%d%d",&n,&m);
Tree.init();
Tree.solve();
return ;
}
SPOJcot2 Count on a tree II (树上莫队)的更多相关文章
- spoj COT2 - Count on a tree II 树上莫队
题目链接 http://codeforces.com/blog/entry/43230树上莫队从这里学的, 受益匪浅.. #include <iostream> #include < ...
- SP10707 COT2 - Count on a tree II (树上莫队)
大概学了下树上莫队, 其实就是在欧拉序上跑莫队, 特判lca即可. #include <iostream> #include <algorithm> #include < ...
- [SPOJ]Count on a tree II(树上莫队)
树上莫队模板题. 使用欧拉序将树上路径转化为普通区间. 之后莫队维护即可.不要忘记特判LCA #include<iostream> #include<cstdio> #incl ...
- SP10707 COT2 - Count on a tree II [树上莫队学习笔记]
树上莫队就是把莫队搬到树上-利用欧拉序乱搞.. 子树自然是普通莫队轻松解决了 链上的话 只能用树上莫队了吧.. 考虑多种情况 [X=LCA(X,Y)] [Y=LCA(X,Y)] else void d ...
- SPOJ COT2 Count on a tree II 树上莫队算法
题意: 给出一棵\(n(n \leq 4 \times 10^4)\)个节点的树,每个节点上有个权值,和\(m(m \leq 10^5)\)个询问. 每次询问路径\(u \to v\)上有多少个权值不 ...
- SPOJCOT2 Count on a tree II
分析 树上莫队裸题. 好博客 树剖的时候不能再次dfs重儿子.(好像是废话,但我因为这个问题调了三小时) 代码 #include<cstdlib> #include<cstdio&g ...
- P4074 [WC2013]糖果公园 树上莫队带修改
题目链接 Candyland 有一座糖果公园,公园里不仅有美丽的风景.好玩的游乐项目,还有许多免费糖果的发放点,这引来了许多贪吃的小朋友来糖果公园游玩. 糖果公园的结构十分奇特,它由 nn 个游览点构 ...
- 【SPOJ】Count On A Tree II(树上莫队)
[SPOJ]Count On A Tree II(树上莫队) 题面 洛谷 Vjudge 洛谷上有翻译啦 题解 如果不在树上就是一个很裸很裸的莫队 现在在树上,就是一个很裸很裸的树上莫队啦. #incl ...
- SPOJ COT2 - Count on a tree II(LCA+离散化+树上莫队)
COT2 - Count on a tree II #tree You are given a tree with N nodes. The tree nodes are numbered from ...
随机推荐
- mac下报错 xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools), missing xcrun at: /Library/Developer/CommandLineTools/usr/bin/xcrun
如题mac下遇到错误: 解决办法:安装mac的命令行工具CommandLineTools xcode-select --install
- Java序列化算法
Serialization(序列化)是一种将对象以一连串的字节描述的过程:反序列化deserialization是一种将这些字节重建成一个对象的过程.java序列化API提供一种处理对象序列化的标准机 ...
- 10934 - Dropping water balloons(DP)
这道题的思路非常难想. 问你须要的最少实验次数,这是非常难求解的.并且我们知道的条件仅仅有三个.k.n.实验次数 . 所以我们最好还是改变思路,转而求最高所能确定的楼层数 . 那么用d[i][j]表 ...
- 【LeetCode】Word Break 解题报告
Given a string s and a dictionary of words dict, determine if s can be segmented into a space-separa ...
- WPF 基础到企业应用系列1——开篇故意
參考资料 提到參考资料,大家第一感觉就是MSDN,当然我也不例外.这个站点基本上是学习微软技术的首选站点,除了这个站点以外,我还參考了非常多其它的社区和站点,基本上都在.NET 技术社区之我见(英文篇 ...
- UVA1422-Processor(二分法+优先队列)
option=com_onlinejudge&Itemid=8&category=512&page=show_problem&problem=4168"> ...
- kubectl技巧之通过go-template截取属性
系列目录 在使用kubectl get获取资源信息的时候,可以通过-o(--output简写形式)指定信息输出的格式,如果指定的是yaml或者json输出的是资源的完整信息,实际工作中,输出内容过少则 ...
- caffe搭建--caffe- win10 vs2015 编译(支持GPU)--注意在cmake的时候需要根据情况仔细修改配置
--http://blog.csdn.net/longji/article/details/60964998 注意: 在cmake的时候需要根据情况仔细修改配置,比如,如果gpu的能力不足3.0的话, ...
- 分布式开源调度框架TBSchedule原理与应用
主要内容: 第一部分 TBSchedule基本概念及原理 1. 概念介绍 2. 工作原理 3. 源代码分析 4. 与其它开源调度框架对照 第二部分 TBSchedule分布式调度演示样例 1. TBS ...
- innodb的锁和高并发
1 innodb的锁 1.1 s锁,即读锁,即share锁 1.2 x锁,即写锁,排他锁 1.3 s锁和x锁之间的关系 多个读锁可以共存,但是读锁不可以和写锁共存.写锁和写锁不可以共存. 1.4 间隙 ...