SPOJ10707 COT2 Count on a tree II


Solution

我会强制在线版本! Solution戳这里

代码实现

  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #include<string.h>
  4. #include<math.h>
  5. #include<algorithm>
  6. #include<queue>
  7. #include<set>
  8. #include<map>
  9. #include<iostream>
  10. using namespace std;
  11. #define ll long long
  12. #define re register
  13. #define file(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout)
  14. inline int gi()
  15. {
  16. int f=1,sum=0;char ch=getchar();
  17. while(ch>'9' || ch<'0'){if(ch=='-')f=-1;ch=getchar();}
  18. while(ch>='0' && ch<='9'){sum=(sum<<3)+(sum<<1)+ch-'0';ch=getchar();}
  19. return f*sum;
  20. }
  21. const int N=60010;
  22. int Bl[N],B,P[N],ans[310][N],a[N],b[N],bl[N],num,p[N][310],Anum,rt[310],F[N];
  23. struct array
  24. {
  25. int num[210];
  26. int operator[](int x){return p[num[Bl[x]]][P[x]];};
  27. void insert(const array &pre,int x,int dep)
  28. {
  29. int block=Bl[x],t=P[x];
  30. memcpy(num,pre.num,sizeof(num));
  31. memcpy(p[++Anum],p[num[block]],sizeof(p[0]));
  32. p[Anum][t]=dep;num[block]=Anum;
  33. }
  34. }s[N];
  35. int to[N<<1],nxt[N<<1],front[N],cnt,dep[N],f[N][22],st[N],sta,kind;
  36. inline void Add(int u,int v)
  37. {
  38. to[++cnt]=v;nxt[cnt]=front[u];front[u]=cnt;
  39. }
  40. inline int dfs(int u,int fa)
  41. {
  42. dep[u]=dep[fa]+1;
  43. f[u][0]=fa;
  44. s[u].insert(s[fa],a[u],dep[u]);
  45. st[++sta]=u;int mx=dep[u],now=sta;
  46. for(re int i=front[u];i;i=nxt[i])
  47. {
  48. int v=to[i];
  49. if(v==fa)continue;
  50. mx=max(mx,dfs(v,u));
  51. }
  52. if(mx-dep[u]>=B || now==1)
  53. {
  54. rt[++num]=u;
  55. for(re int i=now;i<=sta;i++)bl[st[i]]=num;
  56. sta=now-1;return dep[u]-1;
  57. }
  58. return mx;
  59. }
  60. int lca(int u,int v)
  61. {
  62. if(dep[u]<dep[v])swap(u,v);
  63. for(re int i=20;~i;i--)
  64. if(dep[u]-(1<<i)>=dep[v])u=f[u][i];
  65. if(u==v)return u;
  66. for(re int i=20;~i;i--)
  67. if(f[u][i]!=f[v][i])
  68. u=f[u][i],v=f[v][i];
  69. return f[u][0];
  70. }
  71. inline void getans(int u,int fa,int BL)
  72. {
  73. if(++F[a[u]]==1)kind++;
  74. ans[BL][u]=kind;
  75. for(re int i=front[u];i;i=nxt[i])
  76. {
  77. int v=to[i];
  78. if(v==fa)continue;
  79. getans(v,u,BL);
  80. }
  81. if(--F[a[u]]==0)kind--;
  82. }
  83. int solve_same(int x,int y)
  84. {
  85. sta=0;
  86. for(kind=0;x!=y;x=f[x][0])
  87. {
  88. if(dep[x]<dep[y])swap(x,y);
  89. if(!F[a[x]]++)++kind,st[++sta]=a[x];
  90. }
  91. int QAQ=kind+(!F[a[x]]);
  92. for(;sta;sta--)F[st[sta]]=0;
  93. return QAQ;
  94. }
  95. int solve_diff(int x,int y)
  96. {
  97. if(dep[rt[bl[x]]]<dep[rt[bl[y]]])swap(x,y);
  98. int sum=ans[bl[x]][y];
  99. int z=rt[bl[x]],d=dep[lca(x,y)];
  100. sta=0;
  101. for(;x!=z;x=f[x][0])
  102. {
  103. if(!F[a[x]] && s[z][a[x]]<d && s[y][a[x]]<d)
  104. F[st[++sta]=a[x]]=1,sum++;
  105. }
  106. for(;sta;sta--)F[st[sta]]=0;
  107. return sum;
  108. }
  109. int n,m;
  110. void print(int x)
  111. {
  112. if(x>=10)print(x/10);
  113. putchar(x%10+'0');
  114. }
  115. int main()
  116. {
  117. n=gi();m=gi();B=sqrt(n);
  118. for(int i=1;i<=n;i++)Bl[i]=(i-1)/B+1,P[i]=i%B;
  119. for(re int i=1;i<=n;i++)a[i]=b[i]=gi();
  120. sort(b+1,b+n+1);int N=unique(b+1,b+n+1)-b-1;
  121. for(re int i=1;i<=n;i++)
  122. a[i]=lower_bound(b+1,b+N+1,a[i])-b;
  123. for(re int i=1;i<n;i++)
  124. {
  125. int u=gi(),v=gi();
  126. Add(u,v);Add(v,u);
  127. }
  128. dfs(1,1);
  129. for(re int i=1;i<=num;i++)getans(rt[i],rt[i],i);
  130. for(re int j=1;j<=20;j++)
  131. for(re int i=1;i<=n;i++)
  132. f[i][j]=f[f[i][j-1]][j-1];
  133. int lastans=0;
  134. while(m--)
  135. {
  136. int u=gi(),v=gi();
  137. if(bl[u]==bl[v])lastans=solve_same(u,v);
  138. else lastans=solve_diff(u,v);
  139. print(lastans);putchar('\n');
  140. }
  141. return 0;
  142. }

【SPOJ10707】 COT2 Count on a tree II的更多相关文章

  1. 【SPOJ10707】COT2 - Count on a tree II

    题目大意:给定一棵 N 个节点的无根树,每个节点有一个颜色.现有 M 个询问,每次询问一条树链上的不同颜色数. 题解:学会了树上莫队. 树上莫队是将节点按照欧拉序进行排序,将树上问题转化成序列上的问题 ...

  2. 【树上莫队】【SP10707】 COT2 - Count on a tree II

    Description 给定一棵 \(n\) 个点的树,每个节点有一个权值,\(m\) 次询问,每次查询两点间路径上有多少不同的权值 Input 第一行是 \(n\) 和 \(m\) 第二行是 \(n ...

  3. spoj COT2 - Count on a tree II

    COT2 - Count on a tree II http://www.spoj.com/problems/COT2/ #tree You are given a tree with N nodes ...

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

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

    COT2 - Count on a tree II You are given a tree with N nodes. The tree nodes are numbered from 1 to N ...

  6. SPOJ10707 COT2 - Count on a tree II 【树上莫队】

    题目分析: 考虑欧拉序,这里的欧拉序与ETT欧拉序的定义相同而与倍增LCA不同.然后不妨对于询问$u$与$v$让$dfsin[u] \leq dfsin[v]$,这样对于u和v不在一条路径上,它们可以 ...

  7. 【SPOJ】10628. Count on a tree(lca+主席树+dfs序)

    http://www.spoj.com/problems/COT/ (速度很快,排到了rank6) 这题让我明白了人生T_T 我知道我为什么那么sb了. 调试一早上都在想人生. 唉. 太弱. 太弱. ...

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

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

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

随机推荐

  1. 【转】C#异步的世界【下】

    [转]C#异步的世界[下] 接上篇:<C#异步的世界[上]> 上篇主要分析了async\await之前的一些异步模式,今天说异步的主要是指C#5的async\await异步.在此为了方便的 ...

  2. QualNet/EXata的发展贯穿在美军网络中心战演进的始终

    QualNet/EXata的发展贯穿在美军网络中心战演进的始终 赵玉亭 1.   QualNet/EXata的前身GloMoSim是美国防部高级计划研究局(DARPA)在1994年启动的全球移动信息系 ...

  3. Java HttpURLConnection 下载图片 图片全是“加密图片”文字,怎么解决?

    package com.qzf.util; import java.io.FileOutputStream;import java.io.IOException;import java.io.Inpu ...

  4. 2018.11.01 NOIP训练 梭哈(模拟)

    传送门 这题貌似不考智商啊. 直接按题意写就可以了. 事实上把牌从小到大排序之后写起来很舒服的. 然后就是有些地方可以人脑减代码量和判断次数. (提示:满堂红和某几种同类型的牌的大小判断) 然后注意A ...

  5. boost--BOOST_AUTO、typeof、result_of

    1.BOOST_AUTO BOOST_AUTO的功能类似于auto和any,可以用来定义任意类型数据,且可以在编译时自动推导出表达式的类型.BOOST_AUTO属于boost中的typeof库,使用需 ...

  6. C语言程序设计50例(三)(经典收藏)

    [程序31]题目:请输入星期几的第一个字母来判断一下是星期几,如果第一个字母一样,则继续 判断第二个字母.1.程序分析:用情况语句比较好,如果第一个字母一样,则判断用情况语句或if语句判断第二个字母. ...

  7. 内联/块级元素的宽高及margin/padding的说明 |||||| 为何img、input等内联元素可以设置宽、高

    1,内联非替换元素设置宽高是无效的,设置margin时,左右有效,上下无效.设置padding时,左右有效,而上下padding比较奇葩,内联非替换元素的上下padding会在元素内容盒不动的情况下上 ...

  8. w7 目录

    第17章 期中架构体系介绍 期中架构环境准备 01-期中架构内容简介 02-期中架构大酒楼详解 03-期中架构使用到的软件简介 04-期中架构运维角度观察与使用的软件 05-重头开始创建一台新的虚拟机 ...

  9. 安卓修改开机logo

    这里我们是在ubuntu下进行操作我是用root用户登陆的,首先安装netpbm库 执行:apt-get install netpbm 对于Android系统最开始表现logo是在内核当中,所以首先我 ...

  10. struts2访问web资源

    通过ActionContext访问 public class TestActionContextAction { public String execute(){ //获取 ActionContext ...