COT2 - Count on a tree II

http://www.spoj.com/problems/COT2/

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

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

  1. Input:
  2. 8 2
  3. 105 2 9 3 8 5 7 7
  4. 1 2
  5. 1 3
  6. 1 4
  7. 3 5
  8. 3 6
  9. 3 7
  10. 4 8
  11. 2 5
  12. 7 8
  1. Output:
  2. 4
  3. 4
 

题意:问树上两点间有多少不同的权值

树上莫队

开始狂T,发现自己竟是按节点编号划分的块!!

dfs分块。。

  1. #include<cmath>
  2. #include<cstdio>
  3. #include<algorithm>
  4. using namespace std;
  5. #define N 40001
  6. #define M 100001
  7. int n,m,siz,tmp;
  8. int hash[N],key[N];
  9. int front[N],to[N*],nxt[N*],tot;
  10. int fa[N],deep[N],id[N],son[N],bl[N],block[N];
  11. bool vis[N];
  12. int sum[N],ans[M];
  13. struct node
  14. {
  15. int l,r,id;
  16. bool operator < (node p) const
  17. {
  18. if(block[l]!=block[p.l]) return block[l]<block[p.l];
  19. return block[r]<block[p.r];
  20. }
  21. }e[M];
  22. int read(int &x)
  23. {
  24. x=; char c=getchar();
  25. while(c<''||c>'') c=getchar();
  26. while(c>=''&&c<='') { x=x*+c-''; c=getchar(); }
  27. }
  28. void add(int x,int y)
  29. {
  30. to[++tot]=y; nxt[tot]=front[x]; front[x]=tot;
  31. to[++tot]=x; nxt[tot]=front[y]; front[y]=tot;
  32. }
  33. void dfs(int x)
  34. {
  35. son[x]++;
  36. for(int i=front[x];i;i=nxt[i])
  37. {
  38. if(to[i]==fa[x]) continue;
  39. deep[to[i]]=deep[x]+;
  40. fa[to[i]]=x;
  41. dfs(to[i]);
  42. son[x]+=son[to[i]];
  43. }
  44. }
  45. void dfs2(int x,int top)
  46. {
  47. id[x]=++tot;
  48. bl[x]=top;
  49. block[x]=(tot-)/siz+;
  50. int y=;
  51. for(int i=front[x];i;i=nxt[i])
  52. {
  53. if(to[i]==fa[x]) continue;
  54. if(son[to[i]]>son[y]) y=to[i];
  55. }
  56. if(!y) return;
  57. dfs2(y,top);
  58. for(int i=front[x];i;i=nxt[i])
  59. {
  60. if(to[i]==fa[x]||to[i]==y) continue;
  61. dfs2(to[i],to[i]);
  62. }
  63. }
  64. void point(int u)
  65. {
  66. if(vis[u]) tmp-=(!--sum[hash[u]]);
  67. else tmp+=(++sum[hash[u]]==);
  68. vis[u]^=;
  69. }
  70. void path(int u,int v)
  71. {
  72. while(u!=v)
  73. {
  74. if(deep[u]>deep[v]) point(u),u=fa[u];
  75. else point(v),v=fa[v];
  76. }
  77. }
  78. int get_lca(int u,int v)
  79. {
  80. while(bl[u]!=bl[v])
  81. {
  82. if(deep[bl[u]]<deep[bl[v]]) swap(u,v);
  83. u=fa[bl[u]];
  84. }
  85. return deep[u]<deep[v] ? u : v;
  86. }
  87. int main()
  88. {
  89. read(n);read(m); siz=sqrt(n);
  90. for(int i=;i<=n;i++) read(key[i]),hash[i]=key[i];
  91. sort(key+,key+n+);
  92. key[]=unique(key+,key+n+)-(key+);
  93. for(int i=;i<=n;i++) hash[i]=lower_bound(key+,key+key[]+,hash[i])-key;
  94. int x,y;
  95. for(int i=;i<n;i++)
  96. {
  97. read(x); read(y);
  98. add(x,y);
  99. }
  100. tot=;
  101. dfs();
  102. dfs2(,);
  103. for(int i=;i<=m;i++)
  104. {
  105. read(e[i].l); read(e[i].r);
  106. e[i].id=i;
  107. }
  108. sort(e+,e+m+);
  109. int L=,R=,lca;
  110. for(int i=;i<=m;i++)
  111. {
  112. if(id[e[i].l]>id[e[i].r]) swap(e[i].l,e[i].r);
  113. path(L,e[i].l);
  114. path(R,e[i].r);
  115. lca=get_lca(e[i].l,e[i].r);
  116. point(lca);
  117. ans[e[i].id]=tmp;
  118. point(lca);
  119. L=e[i].l; R=e[i].r;
  120. }
  121. for(int i=;i<=m;i++) printf("%d\n",ans[i]);
  122. }
 

spoj COT2 - Count on a tree II的更多相关文章

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

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

    题目链接:http://www.spoj.com/problems/COT2/ You are given a tree with N nodes.The tree nodes are numbere ...

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

    题目链接:http://www.spoj.com/problems/COT2/ 参考博客:http://www.cnblogs.com/xcw0754/p/4763804.html上面这个人推导部分写 ...

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

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

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

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

  6. SPOJ COT2 Count on a tree II (树上莫队,倍增算法求LCA)

    题意:给一个树图,每个点的点权(比如颜色编号),m个询问,每个询问是一个区间[a,b],图中两点之间唯一路径上有多少个不同点权(即多少种颜色).n<40000,m<100000. 思路:无 ...

  7. 【SPOJ10707】 COT2 Count on a tree II

    SPOJ10707 COT2 Count on a tree II Solution 我会强制在线版本! Solution戳这里 代码实现 #include<stdio.h> #inclu ...

  8. 【BZOJ2589】 Spoj 10707 Count on a tree II

    BZOJ2589 Spoj 10707 Count on a tree II Solution 吐槽:这道题目简直...丧心病狂 如果没有强制在线不就是树上莫队入门题? 如果加了强制在线怎么做? 考虑 ...

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

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

随机推荐

  1. [C++] Fucntions

    Statements A break statements terminate the nearest wile, do while, for or switch statement. A break ...

  2. OpenCV学习4-----K-Nearest Neighbors(KNN)demo

    最近用到KNN方法,学习一下OpenCV给出的demo. demo大意是随机生成两团二维空间中的点,然后在500*500的二维空间平面上,计算每一个点属于哪一个类,然后用红色和绿色显示出来每一个点 如 ...

  3. Alpha发布文案加美工展示

    目录 团队简介 项目进展 组内分工 队员总结 后期计划 一.团队简介 二.项目进展 从选题发布到今天的Alpha发布,我们团队经历了许许多多的磨难.我们最终设计了如下的功能:首页.班级.个人.更多.打 ...

  4. Thunder团队第二周 - Scrum会议5

    Scrum会议5 小组名称:Thunder 项目名称:爱阅app Scrum Master:苗威 工作照片: 参会成员: 王航:http://www.cnblogs.com/wangh013/ 李传康 ...

  5. Mininet实验 MAC地址学习分析

    拓扑图 学习过程分析 首先交换机A和交换机B一开始的MAC地址表都是空的. 此时主机11向主机33发送一个数据帧. 数据帧会先到达交换机A,交换机A会获得主机11的MAC地址和端口号.(此时交换机A的 ...

  6. 团队选题报告(i know)

    一.团队成员及分工 团队名称:I know 团队成员: 陈家权:选题报告word撰写 赖晓连:ppt制作,原型设计 雷晶:ppt制作,原型设计 林巧娜:原型设计,博客随笔撰写 庄加鑫:选题报告word ...

  7. lintcode-173-链表插入排序

    173-链表插入排序 用插入排序对链表排序 样例 Given 1->3->2->0->null, return 0->1->2->3->null 标签 ...

  8. Debian实验机 常用命令

    1.开启中文输入法 fcitx 2. 开启无线连接 wicd 3. 远程连接 ssh root@XXX.XXX.XXX.XXX 4. 启动Ulipad ~/ulipad-master# python ...

  9. python爬虫:爬取网站视频

    python爬取百思不得姐网站视频:http://www.budejie.com/video/ 新建一个py文件,代码如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 1 ...

  10. BZOJ4028 HEOI2015公约数数列(分块)

    前缀gcd的变化次数是log的,考虑对每一种gcd查询,问题变为查询一段区间是否存在异或前缀和=x/gcd. 无修改的话显然可以可持久化trie,但这玩意实在没法支持修改.于是考虑分块. 对于每一块将 ...