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. 9.【nuxt起步】-scroll分页加载

    面是单页,下面实现一个列表页和分页加载的例子 1.新建pages/list.vue <template> <div> 分页加载列表页面 </div> </te ...

  2. python 工具 二进制文件处理之——去掉指定长度数据包头

    包头48bit 数据98464 ...如此循环: piece_size = 48 piece_size1 = 98464 with open("C:\\Users\\Administrato ...

  3. SQL中Inserted 和Deleted表 以及触发Trigger

    什么是Inserted 和Deleted表 他们有什么用 trigger 的简单实用 1.什么是Inserted 和Deleted表 当插入数据的时候,其实是同时向目的表 和inserted表中插入数 ...

  4. persits.jpeg 水印组件

    官方下载的persits.jpeg 都须要注冊.不然就有时间限制.可今天须要个persits.jpeg 破解版安装到server上,可百度了半天也没找到.最后还是找到了. 很捧的水印组件,玩serve ...

  5. vue2.0 自定义指令

    Vue指令 Vue的指令以v-开头,作用在HTML元素上,将指令绑定在元素上,给绑定的元素添加一些特殊行为. 例如: <h1 v-if="yes">Yes</h1 ...

  6. maximum-depth-of-binary-tree——找出数的最大深度

    Given a binary tree, find its maximum depth. The maximum depth is the number of nodes along the long ...

  7. 微信自带浏览器被输入法阻挡文本框的 jQuery 解决方法 by FungLeo

    微信自带浏览器被输入法阻挡文本框的 jQuery 解决方法 by FungLeo 前言 做好了项目之后,在各种浏览器里面測试,都没有问题.非常高兴,交付后端使用.然而发如今微信自带浏览器里面,却是出现 ...

  8. ListView 自己定义BaseAdapter实现单选打勾(无漏洞)

    (假设须要完整demo,请评论留下邮箱) (眼下源代码已经不发送.假设须要源代码,加qq316701116.不喜勿扰) 近期由于一个项目的原因须要自己定义一个BaseAdapter实现ListVIew ...

  9. Django1.11.4中文文档

    Django管理站点¶ 自动管理界面是Django最强大的部分之一.它从您的模型中读取元数据,以提供一个快速,以模型为中心的界面,让受信任的用户可以管理您网站上的内容.管理员建议的使用仅限于组织的内部 ...

  10. AndroidManifest具体解释之Application(有图更好懂)

    可以包括的标签: <activity> <activity-alias> <service> <receiver> <provider> & ...