hdu5111

链接

hdu

思路

先考虑序列上如何解决。

  1. 1 3 2 5 4
  2. 1 2 4 5 3

这个序列变成

  1. 1 2 3 4 5
  2. 1 3 5 5 2

是对答案没有影响的(显然)。

然后查询操作\(l,r,L,R\)就是,

一段连续的区间\([L,R]\)内包含几个值在\([l,r]\)的数字个数.

主席树就可以做了。

\(query(rt[L-1],rt[R],[l,r]的和)\)

可以用树链剖分把树上问题转化成链上。

左边一棵树树链剖分,每一条链子都是一段连续的。

右边一棵树根据父子关系建立主席树。

然后向上跳统计贡献。

吐槽

本来我写完之后可以两遍编译,一遍样例,一遍AC的。

鬼知道我清空出了什么毛病。

  1. for(i 0 to limit-1) a[i]=0

居然清空不了。

debug了半天,换成了memset才过。

我也是醉了。

代码

  1. #include <iostream>
  2. #include <map>
  3. #include <cstring>
  4. #include <algorithm>
  5. #define ls(x) (t[x].ls)
  6. #define rs(x) (t[x].rs)
  7. using namespace std;
  8. const int _=1e5+7;
  9. int read() {
  10. int x=0,f=1;char s=getchar();
  11. for(;s>'9'||s<'0';s=getchar()) if(s=='-') f=-1;
  12. for(;s>='0'&&s<='9';s=getchar()) x=x*10+s-'0';
  13. return x*f;
  14. }
  15. int n1,n2,w1[_],w2[_],rt[_];
  16. map<int,int> dsr;
  17. struct node {
  18. int v,nxt;
  19. }e1[_<<1],e2[_<<1];
  20. int head1[_],head2[_],tot1,tot2;
  21. void add1(int u,int v) {
  22. e1[++tot1].v=v;
  23. e1[tot1].nxt=head1[u];
  24. head1[u]=tot1;
  25. }
  26. void add2(int u,int v) {
  27. e2[++tot2].v=v;
  28. e2[tot2].nxt=head2[u];
  29. head2[u]=tot2;
  30. }
  31. namespace ZXS {
  32. struct node {
  33. int ls,rs,tot;
  34. }t[_*30];
  35. int cnt;
  36. void clear() {
  37. memset(t,0,sizeof(t));
  38. // for(int i=0;i<=cnt;++i)
  39. // ls(i)=rs(i)=t[i].tot=0;
  40. cnt=0;
  41. }
  42. void insert(int l,int r,int k,int x,int &y) {
  43. t[y=++cnt]=t[x];
  44. t[y].tot++;
  45. if(l==r) return;
  46. int mid=(l+r)>>1;
  47. if(k<=mid) insert(l,mid,k,ls(x),ls(y));
  48. else insert(mid+1,r,k,rs(x),rs(y));
  49. }
  50. int query(int l,int r,int L,int R,int x,int y) {
  51. if(L<=l&&r<=R) return t[y].tot-t[x].tot;
  52. int mid=(l+r)>>1,ans=0;
  53. if(L<=mid) ans+=query(l,mid,L,R,ls(x),ls(y));
  54. if(R>mid) ans+=query(mid+1,r,L,R,rs(x),rs(y));
  55. return ans;
  56. }
  57. }
  58. namespace LCA{
  59. int siz[_],son[_],top[_],f[_],dep[_],idx[_],cnt;
  60. void clear() {
  61. cnt=0;
  62. memset(idx,0,sizeof(idx));
  63. // memset(siz,0,sizeof(siz));
  64. memset(son,0,sizeof(son));
  65. // memset(top,0,sizeof(top));
  66. // memset(dep,0,sizeof(dep));
  67. // memset(f,0,sizeof(f));
  68. }
  69. void dfs1(int u,int fa) {
  70. dep[u]=dep[fa]+1;
  71. f[u]=fa;
  72. siz[u]=1;
  73. for(int i=head2[u];i;i=e2[i].nxt) {
  74. int v=e2[i].v;
  75. if(v==fa) continue;
  76. dfs1(v,u);
  77. siz[u]+=siz[v];
  78. if(siz[v]>siz[son[u]]) son[u]=v;
  79. }
  80. }
  81. void dfs2(int u,int topf) {
  82. idx[u]=++cnt;
  83. top[u]=topf;
  84. if(!son[u]) return;
  85. dfs2(son[u],topf);
  86. for(int i=head2[u];i;i=e2[i].nxt) {
  87. int v=e2[i].v;
  88. if(!idx[v]) dfs2(v,v);
  89. }
  90. }
  91. int query(int x,int y) {
  92. while(top[x]!=top[y]) {
  93. if(dep[top[x]]<dep[top[y]]) swap(x,y);
  94. x=f[top[x]];
  95. }
  96. if(dep[x]>dep[y]) swap(x,y);
  97. return x;
  98. }
  99. }
  100. namespace SLPF{
  101. int siz[_],son[_],top[_],f[_],dep[_],idx[_],cnt;
  102. void clear() {
  103. cnt=0;
  104. memset(idx,0,sizeof(idx));
  105. // memset(siz,0,sizeof(siz));
  106. memset(son,0,sizeof(son));
  107. // memset(top,0,sizeof(top));
  108. // memset(dep,0,sizeof(dep));
  109. // memset(f,0,sizeof(f));
  110. }
  111. void dfs1(int u,int fa) {
  112. dep[u]=dep[fa]+1;
  113. f[u]=fa;
  114. siz[u]=1;
  115. for(int i=head1[u];i;i=e1[i].nxt) {
  116. int v=e1[i].v;
  117. if(v==fa) continue;
  118. dfs1(v,u);
  119. siz[u]+=siz[v];
  120. if(siz[v]>siz[son[u]]) son[u]=v;
  121. }
  122. }
  123. void dfs2(int u,int topf) {
  124. idx[u]=++cnt;
  125. dsr[w1[u]]=cnt;
  126. top[u]=topf;
  127. if(!son[u]) return;
  128. dfs2(son[u],topf);
  129. for(int i=head1[u];i;i=e1[i].nxt) {
  130. int v=e1[i].v;
  131. if(!idx[v]) dfs2(v,v);
  132. }
  133. }
  134. void QQ(int x,int y,int u2,int v2) {
  135. int lca=LCA::query(u2,v2),ans=0;
  136. while(top[x]!=top[y]) {
  137. if(dep[top[x]]<dep[top[y]]) swap(x,y);
  138. ans+=ZXS::query(1,n1,idx[top[x]],idx[x],rt[lca],rt[u2]);
  139. // cout<<ZXS::query(1,n1,idx[top[x]],idx[x],rt[lca],rt[u2])<<"\n";
  140. ans+=ZXS::query(1,n1,idx[top[x]],idx[x],rt[LCA::f[lca]],rt[v2]);
  141. // cout<<ZXS::query(1,n1,idx[top[x]],idx[x],rt[LCA::f[lca]],rt[v2])<<"\n";
  142. x=f[top[x]];
  143. }
  144. if(dep[x]>dep[y]) swap(x,y);
  145. ans+=ZXS::query(1,n1,idx[x],idx[y],rt[lca],rt[u2]);
  146. // cout<<ZXS::query(1,n1,idx[x],idx[y],rt[lca],rt[u2])<<"\n";
  147. ans+=ZXS::query(1,n1,idx[x],idx[y],rt[LCA::f[lca]],rt[v2]);
  148. // cout<<ZXS::query(1,n1,idx[x],idx[y],rt[LCA::f[lca]],rt[v2])<<"\n";
  149. printf("%d\n",ans);
  150. }
  151. }
  152. void dfs(int u,int fa) {
  153. if(dsr.count(w2[u])) ZXS::insert(1,n1,dsr[w2[u]],rt[fa],rt[u]);
  154. else rt[u]=rt[fa];
  155. for(int i=head2[u];i;i=e2[i].nxt) {
  156. int v=e2[i].v;
  157. if(v==fa) continue;
  158. dfs(v,u);
  159. }
  160. }
  161. int main() {
  162. // freopen("data.in","r",stdin);
  163. // freopen("a.out","w",stdout);
  164. while(scanf("%d",&n1)!=EOF) {
  165. //clear
  166. LCA::clear();
  167. SLPF::clear();
  168. ZXS::clear();
  169. dsr.clear();
  170. tot1=tot2=0;
  171. memset(rt,0,sizeof(rt));
  172. memset(head1,0,sizeof(head1));
  173. memset(head2,0,sizeof(head2));
  174. //read
  175. for(int i=2;i<=n1;++i) {
  176. int u=i,v=read();
  177. // cout<<u<<"->"<<v<<"\n";
  178. add1(u,v),add1(v,u);
  179. }
  180. for(int i=1;i<=n1;++i) w1[i]=read();
  181. n2=read();
  182. for(int i=2;i<=n2;++i) {
  183. int u=i,v=read();
  184. // cout<<u<<"->"<<v<<"\n";
  185. add2(u,v),add2(v,u);
  186. }
  187. for(int i=1;i<=n2;++i) w2[i]=read();
  188. //init
  189. SLPF::dfs1(1,0);
  190. SLPF::dfs2(1,1);
  191. LCA::dfs1(1,0);
  192. LCA::dfs2(1,1);
  193. dfs(1,0);
  194. //ask
  195. int Q=read();
  196. while(Q --> 0) {
  197. int u1=read(),v1=read(),u2=read(),v2=read();
  198. SLPF::QQ(u1,v1,u2,v2);
  199. }
  200. }
  201. return 0;
  202. }

hdu5111 树链剖分,主席树的更多相关文章

  1. dfs序+主席树 或者 树链剖分+主席树(没写) 或者 线段树套线段树 或者 线段树套splay 或者 线段树套树状数组 bzoj 4448

    4448: [Scoi2015]情报传递 Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 588  Solved: 308[Submit][Status ...

  2. Codechef FIBTREE 树链剖分 主席树 LCA 二次剩余 快速幂

    原文链接https://www.cnblogs.com/zhouzhendong/p/CC-FIBTREE.html 题目传送门 - CC-FIBTREE 题意 给定一个有 $n$ 个节点,初始点权都 ...

  3. BZOJ1146 [CTSC2008]网络管理Network 树链剖分 主席树 树状数组

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1146 题意概括 在一棵树上,每一个点一个权值. 有两种操作: 1.单点修改 2.询问两点之间的树链 ...

  4. bzoj 4448 [Scoi2015]情报传递 (树链剖分+主席树)

    题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=4448 题面: Description 奈特公司是一个巨大的情报公司,它有着庞大的情报网络 ...

  5. BZOJ 4448: [Scoi2015]情报传递 树链剖分 主席树

    4448: [Scoi2015]情报传递 题目连接: http://www.lydsy.com/JudgeOnline/problem.php?id=4448 Description 奈特公司是一个巨 ...

  6. [GDOI2016][树链剖分+主席树]疯狂动物城

    题面 Description Nick 是只在动物城以坑蒙拐骗为生的狐狸,儿时受到偏见的伤害,放弃了自己的理想.他被兔子 Judy 设下圈套,被迫与她合作查案,而卷入意想不到的阴谋,历尽艰险后成为搭档 ...

  7. HDU 5111 Alexandra and Two Trees 树链剖分 + 主席树

    题意: 给出两棵树,每棵树的节点都有一个权值. 同一棵树上的节点的权值互不相同,不同树上节点的权值可以相同. 要求回答如下询问: \(u_1 \, v_1 \, u_2 \, v_2\):询问第一棵树 ...

  8. 5.15 牛客挑战赛40 E 小V和gcd树 树链剖分 主席树 树状数组 根号分治

    LINK:小V和gcd树 时限是8s 所以当时好多nq的暴力都能跑过. 考虑每次询问暴力 跳父亲 这样是nq的 4e8左右 随便过. 不过每次跳到某个点的时候需要得到边权 如果直接暴力gcd的话 nq ...

  9. BZOJ3531 SDOI2014 旅行 - 树链剖分,主席树

    题意:给定一棵树,树上每个点有权值和类型.支持:修改某个点的类型:修改某个点的权值:询问某条链上某个类型的点的和/最大值.点数/类型数/询问数<=100000. 分析: 树链剖分,对每个类型的点 ...

  10. BZOJ4012 HNOI2015开店(树链剖分+主席树)

    考虑这样一个问题:一棵树初始全是白点,有两种操作:把一个点染黑:询问某点到所有黑点的距离之和. 注意到树上两点x和y的距离为depth[x]+depth[y]-depth[lca(x,y)]*2.要求 ...

随机推荐

  1. Phaser也可以实现countdownLatch的功能

    /** * 可用用phaser模拟countDownLatch * awaitAdvance方法:如果传入的参数和当前的phase相等,线程就阻塞住等待phase的值增加:否则就立即返回 */ pub ...

  2. Luogu P2727 【01串 Stringsobits】

    看到题解里好像都是用$DP$解决的,本着禁止DP的原则,我来提供一发纯数学其实和DP本质相同的题解,前两天刚反演题,脑子炸了,本来说换换脑子,结果还是数学 首先受进制思想启发,我们不妨按位考虑,考虑这 ...

  3. javascirpt的json.stringify()方法在IE浏览器兼容性模式下出错的原因与解决办法

    今天开机混底薪的时候遇到一个JSON.stringify()在IE浏览器兼容模式下的问题. 问题描述 一个弹窗选择的功能原来好好的,突然就不行了. 想要调试调试不了,报错信息也看不到(一开F12这破I ...

  4. 项目Gradle版本从4.4升级到4.6

    一.背景 Gralde版本与AGP(Android Gradle Plugin)版本具有一定的对应关系,原因在于AGP实质上作为Gradle的插件,依赖于Gradle作为宿主.因此,不同的AGP版本需 ...

  5. 【02】Saltstack:Grains and Pillar

    写在前面的话 上一节谈及了 Saltstack 的安装和初始化配置,本节将谈谈 Saltstack 中两个重要的东西,Grains 和 Pillar. 数据系统 Grains 入门 Grains 是静 ...

  6. 查看索引在哪些ES集群节点上的命令

    用途:迁移数据到其他节点上的时候需要用这个 GET /_cat/shards GET /_cat/shards?h=n

  7. fancybit个人简介

    程序员一枚 熟悉C C++ C# js lua等多种常见开发语言 熟悉Unity游戏开发 node.js pomelo和C# scut 网游后端框架 做过.net和php网站后端 二次元文化爱好者 有 ...

  8. css权重等级

    1.问题起因(在一次偶然编写css发现的,.div2 p>.div1 p>.p1,然后做了测试并找查相关资料) 2.解决方案 首先看哪一级的权重高 1.!important,加在样式属性值 ...

  9. moodle3.7中文语言包

    Moodle官方有中文语言包,但是还有没有翻译的,为了提高用户体验,可以将部分未翻译的应用在Moodle网站管理中自己修改. 具体步骤: 先确定需要修改的关键字,也就是网站中没有翻译成中文的文字 在c ...

  10. Chrome headless三种安装方法

    在使用chrome headless的时候,使用安装源有很多的依赖问题,提供三种方法,最简单的是使用一键安装脚本. 1.添加chrome源来安装chrome 添加源: ## 添加:vim /etc/y ...