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 (uv).

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 (树上莫队)的更多相关文章

  1. spoj COT2 - Count on a tree II 树上莫队

    题目链接 http://codeforces.com/blog/entry/43230树上莫队从这里学的,  受益匪浅.. #include <iostream> #include < ...

  2. SP10707 COT2 - Count on a tree II (树上莫队)

    大概学了下树上莫队, 其实就是在欧拉序上跑莫队, 特判lca即可. #include <iostream> #include <algorithm> #include < ...

  3. [SPOJ]Count on a tree II(树上莫队)

    树上莫队模板题. 使用欧拉序将树上路径转化为普通区间. 之后莫队维护即可.不要忘记特判LCA #include<iostream> #include<cstdio> #incl ...

  4. SP10707 COT2 - Count on a tree II [树上莫队学习笔记]

    树上莫队就是把莫队搬到树上-利用欧拉序乱搞.. 子树自然是普通莫队轻松解决了 链上的话 只能用树上莫队了吧.. 考虑多种情况 [X=LCA(X,Y)] [Y=LCA(X,Y)] else void d ...

  5. SPOJ COT2 Count on a tree II 树上莫队算法

    题意: 给出一棵\(n(n \leq 4 \times 10^4)\)个节点的树,每个节点上有个权值,和\(m(m \leq 10^5)\)个询问. 每次询问路径\(u \to v\)上有多少个权值不 ...

  6. SPOJCOT2 Count on a tree II

    分析 树上莫队裸题. 好博客 树剖的时候不能再次dfs重儿子.(好像是废话,但我因为这个问题调了三小时) 代码 #include<cstdlib> #include<cstdio&g ...

  7. P4074 [WC2013]糖果公园 树上莫队带修改

    题目链接 Candyland 有一座糖果公园,公园里不仅有美丽的风景.好玩的游乐项目,还有许多免费糖果的发放点,这引来了许多贪吃的小朋友来糖果公园游玩. 糖果公园的结构十分奇特,它由 nn 个游览点构 ...

  8. 【SPOJ】Count On A Tree II(树上莫队)

    [SPOJ]Count On A Tree II(树上莫队) 题面 洛谷 Vjudge 洛谷上有翻译啦 题解 如果不在树上就是一个很裸很裸的莫队 现在在树上,就是一个很裸很裸的树上莫队啦. #incl ...

  9. 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  ...

随机推荐

  1. 在win7上安装visual c++ 2008 redistributable 发生错误error 1935

     方案一.原来服务"Windows Modules Installer"被禁用了, 启用该服务后, 问题就解决了.  方案二. 1.点开始——在运行框里输入regedit,按回车键 ...

  2. DICOM医学图像处理:Deconstructed PACS之Orthanc

    背景: 此篇博文介绍一个开源的.基于WEB的DICOM Server软件.该开源软件完全使用C++编写,不依赖于第三方数据库(内置了SQLite数据库)或其他框架,支持RESTful API设计模式. ...

  3. 利用泛型和反射,管理配置文件,把Model转换成数据行,并把数据行转换成Model

    利用泛型和反射,管理配置文件,把Model转换成数据行,并把数据行转换成Model   使用场景:网站配置项目,为了便于管理,网站有几个Model类来管理配置文件, 比如ConfigWebsiteMo ...

  4. Java、C++、Python、Ruby、PHP、C#和JavaScript的理解

    Java.C++.Python.Ruby.PHP.C#和JavaScript和日本动漫里的那些大家熟悉的动漫人物结合起来.依据他们的身世.个人经历来生动的表达各编程语言的发展历程.原文内容例如以下:  ...

  5. Spring AOP(转载)

    此前对于AOP的使用仅限于声明式事务,除此之外在实际开发中也没有遇到过与之相关的问题.最近项目中遇到了以下几点需求,仔细思考之后,觉得采用AOP 来解决.一方面是为了以更加灵活的方式来解决问题,另一方 ...

  6. git和github菜鸟使用步骤

    刚刚在windows7下安装完git.奉上安装步骤. git安装 安装git程序.运行以下操作: 1. $ cd ~/.ssh    //检查计算机ssh密钥 2.假设没有提示:No such fil ...

  7. C语言,简单计算器【上】

    由于工作需要最近在研究PHP扩展,无可避免的涉及到了C语言.从出了学校以后C语言在实际工作中还没有用到过,所以必须要先进行一点复习工作.个人认为对于熟悉一样东西说最好的方法是上手实践.于是便想起了当时 ...

  8. leetcode dfs Flatten Binary Tree to Linked List

    Flatten Binary Tree to Linked List Total Accepted: 25034 Total Submissions: 88947My Submissions Give ...

  9. opencv中的子库

    1 FLANN 近似最近邻库,NN就是nearest neighbor的缩写. 2 IlmImf Ilm是Industrial light & magic公司的缩写. Imf是image fo ...

  10. 8.JS数据类型

    ① 数据类型:字符串,数字,布尔,数组,对象,Null,Undefined ② JavaScript拥有动态类型.这意味着相同的变量可用作不同的类型: 实例 var x:   //x为undefine ...