http://www.lydsy.com/JudgeOnline/problem.php?id=4012 (题目链接)

题意

  一棵树,每条边有正边权,每个点的点权非负。若干组询问,强制在线,每次查询点权在范围${[L,R]}$之间的点到某一点${U}$的距离和。

Solution

  这道题做法很多啊。动态树分治。

  按照套路,我们存下每个重心的子树到这个重心的距离之和,以及每个重心的子树到这个重心的父亲的距离之和。这两个东西按照点权排序后用一个数组存起来并处理成前缀和,然后每次询问区间${[L,R]}$,我们只需要在子树中二分查找即可。

细节

  样例很强啊,过了样例即可AC。当然记得开LL

代码

  1. // bzoj4012
  2. #include<algorithm>
  3. #include<iostream>
  4. #include<cstdlib>
  5. #include<cstring>
  6. #include<cstdio>
  7. #include<vector>
  8. #include<cmath>
  9. #define LL long long
  10. #define inf 1ll<<30
  11. #define Pi acos(-1.0)
  12. #define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
  13. using namespace std;
  14.  
  15. const int maxn=200010;
  16. int n,head[maxn],a[maxn],par[maxn],len[maxn],bin[30];
  17. int L,R,U,Q,A;
  18.  
  19. struct edge {int to,next,w;}e[maxn<<1];
  20. struct data {
  21. int num;LL w;
  22. friend bool operator < (const data a,const data b) {
  23. return a.num<b.num;
  24. }
  25. };
  26. vector<data> c[maxn],t[maxn];
  27.  
  28. namespace LittleTrick {
  29. int fa[maxn][30],deep[maxn],cnt;
  30. LL d[maxn];
  31.  
  32. void link(int u,int v,int w) {
  33. e[++cnt]=(edge){v,head[u],w};head[u]=cnt;
  34. e[++cnt]=(edge){u,head[v],w};head[v]=cnt;
  35. }
  36. void dfs(int x) {
  37. for (int i=1;i<=20;i++) fa[x][i]=fa[fa[x][i-1]][i-1];
  38. for (int i=head[x];i;i=e[i].next) if (e[i].to!=fa[x][0]) {
  39. deep[e[i].to]=deep[x]+1;
  40. d[e[i].to]=d[x]+e[i].w;
  41. fa[e[i].to][0]=x;
  42. dfs(e[i].to);
  43. }
  44. }
  45. int lca(int x,int y) {
  46. if (deep[x]<deep[y]) swap(x,y);
  47. int t=deep[x]-deep[y];
  48. for (int i=0;bin[i]<=t;i++) if (bin[i]&t) x=fa[x][i];
  49. for (int i=20;i>=0;i--) if (fa[x][i]!=fa[y][i]) x=fa[x][i],y=fa[y][i];
  50. return x==y ? x : fa[x][0];
  51. }
  52. LL dis(int x,int y) {
  53. return d[x]+d[y]-2*d[lca(x,y)];
  54. }
  55. }
  56. using namespace LittleTrick;
  57.  
  58. namespace NodeDivide {
  59. int size[maxn],f[maxn],vis[maxn],sum,Dargen;
  60.  
  61. void caldargen(int x,int fa) {
  62. size[x]=1,f[x]=0;
  63. for (int i=head[x];i;i=e[i].next) if (e[i].to!=fa && !vis[e[i].to]) {
  64. caldargen(e[i].to,x);
  65. size[x]+=size[e[i].to];
  66. f[x]=max(f[x],size[e[i].to]);
  67. }
  68. f[x]=max(f[x],sum-size[x]);
  69. if (f[x]<f[Dargen]) Dargen=x;
  70. }
  71. void caldeep(int x,int fa,int p) {
  72. c[p].push_back((data){a[x],dis(x,p)});
  73. t[p].push_back((data){a[x],par[p] ? dis(x,par[p]) : 0});
  74. for (int i=head[x];i;i=e[i].next)
  75. if (e[i].to!=fa && !vis[e[i].to]) caldeep(e[i].to,x,p);
  76. }
  77. void work(int x) {
  78. vis[x]=1;
  79. t[x].push_back((data){-1,0});t[x].push_back((data){inf,0}); //方便二分查找,不用特判了
  80. c[x].push_back((data){-1,0});c[x].push_back((data){inf,0});
  81. caldeep(x,0,x);
  82. for (int i=head[x];i;i=e[i].next) if (!vis[e[i].to]) {
  83. Dargen=0;sum=size[e[i].to];
  84. caldargen(e[i].to,x);
  85. par[Dargen]=x;
  86. work(Dargen);
  87. }
  88. sort(t[x].begin(),t[x].end());len[x]=t[x].size();
  89. sort(c[x].begin(),c[x].end());len[x]=c[x].size();
  90. for (int i=1;i<len[x];i++) t[x][i].w+=t[x][i-1].w;
  91. for (int i=1;i<len[x];i++) c[x][i].w+=c[x][i-1].w;
  92. }
  93. void Init() {
  94. f[Dargen=0]=inf;sum=n;
  95. caldargen(1,0);
  96. work(Dargen);
  97. }
  98. }
  99. using namespace NodeDivide;
  100.  
  101. namespace Query {
  102. int Lower_bound(int x) {
  103. int l=0,r=len[x],res;
  104. while (l<=r) {
  105. int mid=(l+r)>>1;
  106. if (c[x][mid].num<L) res=mid,l=mid+1;
  107. else r=mid-1;
  108. }
  109. return res;
  110. }
  111. int Upper_bound(int x) {
  112. int l=0,r=len[x],res;
  113. while (l<=r) {
  114. int mid=(l+r)>>1;
  115. if (c[x][mid].num<=R) res=mid,l=mid+1;
  116. else r=mid-1;
  117. }
  118. return res;
  119. }
  120. LL query(int x,int tag) {
  121. LL d1=dis(x,U),res=0;
  122. LL l=Lower_bound(x),r=Upper_bound(x);
  123. res+=(c[x][r].w-c[x][l].w)+(r-l-tag)*d1;
  124. res-=(t[x][r].w-t[x][l].w);
  125. if (!par[x]) return res;
  126. return res+query(par[x],r-l);
  127. }
  128. }
  129. using namespace Query;
  130.  
  131. int main() {
  132. bin[0]=1;for (int i=1;i<=20;i++) bin[i]=bin[i-1]<<1;
  133. scanf("%d%d%d",&n,&Q,&A);
  134. for (int i=1;i<=n;i++) scanf("%d",&a[i]);
  135. for (int u,v,w,i=1;i<n;i++) {
  136. scanf("%d%d%d",&u,&v,&w);
  137. link(u,v,w);
  138. }
  139. dfs(1);
  140. Init();
  141. LL ans=0;
  142. for (int a,b,i=1;i<=Q;i++) {
  143. scanf("%d%d%d",&U,&a,&b);
  144. if (i==1) L=min(a%A,b%A),R=max(a%A,b%A);
  145. else L=min((a+ans)%A,(b+ans)%A),R=max((a+ans)%A,(b+ans)%A);
  146. printf("%lld\n",ans=query(U,0));
  147. }
  148. return 0;
  149. }

【bzoj4012】 HNOI2015—开店的更多相关文章

  1. [BZOJ4012][HNOI2015]开店(动态点分治,树链剖分)

    4012: [HNOI2015]开店 Time Limit: 70 Sec  Memory Limit: 512 MBSubmit: 2168  Solved: 947[Submit][Status] ...

  2. BZOJ4012 [HNOI2015]开店

    Description 风见幽香有一个好朋友叫八云紫,她们经常一起看星星看月亮从诗词歌赋谈到 人生哲学.最近她们灵机一动,打算在幻想乡开一家小店来做生意赚点钱.这样的 想法当然非常好啦,但是她们也发现 ...

  3. BZOJ4012[HNOI2015]开店——树链剖分+可持久化线段树/动态点分治+vector

    题目描述 风见幽香有一个好朋友叫八云紫,她们经常一起看星星看月亮从诗词歌赋谈到 人生哲学.最近她们灵机一动,打算在幻想乡开一家小店来做生意赚点钱.这样的 想法当然非常好啦,但是她们也发现她们面临着一个 ...

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

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

  5. BZOJ4012: [HNOI2015]开店【动态点分治】

    Description 风见幽香有一个好朋友叫八云紫,她们经常一起看星星看月亮从诗词歌赋谈到 人生哲学.最近她们灵机一动,打算在幻想乡开一家小店来做生意赚点钱.这样的 想法当然非常好啦,但是她们也发现 ...

  6. BZOJ4012 [HNOI2015]开店 (动态点分治)

    Description 风见幽香有一个好朋友叫八云紫,她们经常一起看星星看月亮从诗词歌赋谈到 人生哲学.最近她们灵机一动,打算在幻想乡开一家小店来做生意赚点钱.这样的 想法当然非常好啦,但是她们也发现 ...

  7. BZOJ4012 [HNOI2015]开店 【动态点分治 + splay】

    题目链接 BZOJ4012 题解 Mychael并没有A掉,而是T掉了 讲讲主要思路 在点分树上每个点开两棵\(splay\), 平衡树\(A\)维护子树中各年龄到根的距离 平衡树\(B\)维护子树中 ...

  8. 【BZOJ4012】[HNOI2015]开店 动态树分治+二分

    [BZOJ4012][HNOI2015]开店 Description 风见幽香有一个好朋友叫八云紫,她们经常一起看星星看月亮从诗词歌赋谈到人生哲学.最近她们灵机一动,打算在幻想乡开一家小店来做生意赚点 ...

  9. 【BZOJ4012】开店(主席树)

    [BZOJ4012]开店(主席树) 题面 Description 风见幽香有一个好朋友叫八云紫,她们经常一起看星星看月亮从诗词歌赋谈到 人生哲学.最近她们灵机一动,打算在幻想乡开一家小店来做生意赚点钱 ...

  10. [HNOI2015]开店 树链剖分,主席树

    [HNOI2015]开店 LG传送门 蒟蒻表示不会动态淀粉质. 先把点按年龄排序, 设\(dis[i]\)表示\(i\)到根的距离. 把我们要算的东西稍微变下形:\(ans\) \[ = \sum \ ...

随机推荐

  1. 20155213免考项目——简易的HIDAttack

    20155213免考项目--简易的HIDAttack 听5214说他做不出来自己的免考项目,于是就转向bof进阶,并且成功做出了64位的ROP攻击...... 既然如此,那我就再做一个吧,但都已经期末 ...

  2. 20155330 《网络对抗》 Exp5 MSF基础应用

    20155330 <网络对抗> Exp5 MSF基础应用 实践过程记录 主动攻击实践:MS08_067漏洞攻击 攻击机:kali IP地址:192.168.124.132 靶机:windo ...

  3. webVR全景图多种方案实现(pannellum,aframe,Krpano,three,jquery-vrview)

    前言 有一篇文章我说了H5实现全景图预览,全景视频播放的原理,有需要的小伙伴可以自行去看一下 今天我就拿出我的实践干货出来,本人实测实测过 需求 老板:我需要可以上传全景图片,然后手机网站上都可以36 ...

  4. JQ_开发经验

    1. 把你的代码全部放在闭包里面 这是我用的最多的一条.但是有时候在闭包外面的方法会不能调用.不过你的插件的代码只为你自己的插件服务,所以不存在这个问题,你可以把所有的代码都放在闭包里面.而方法可能应 ...

  5. Unity接入监控摄像头

    公网RTSP测试地址: rtsp://184.72.239.149/vod/mp4://BigBuckBunny_175k.mov RTSP测试软件: EasyPlayerRTSP: https:// ...

  6. 汉码盘点机PDA无缝对接思迅思迅盘点机思迅条码数据采集器批号商品盘点的方法

    1.1.    盘点批号 如果某些商品进行了批号管理,我们不仅仅要清点什么商品总数有多少个,我们还要区分该商品的某个批号有多少个数量,因此以前批号盘点工作量是非常大的. 我们的盘点机PDA支持批号盘点 ...

  7. python爬虫-使用cookie登录

    前言: 什么是cookie? Cookie,指某些网站为了辨别用户身份.进行session跟踪而储存在用户本地终端上的数据(通常经过加密). 比如说有些网站需要登录后才能访问某个页面,在登录之前,你想 ...

  8. ajax请求超时判断(转载)

    ajax请求时有个参数可以借鉴一下 var ajaxTimeOut = $.ajax({ url:'', //请求的URL timeout : 1000, //超时时间设置,单位毫秒 type : ' ...

  9. linux第三章学习笔记

    第三章 进程管理 进程是Unix操作系统抽象概念中最基本的一种. 进程管理是所有操作系统的心脏所在. 一.进程 1. 进程是处于执行期的程序.除了可执行程序代码,还包括打开的文件.挂起的信号.内核内部 ...

  10. SSM 框架快速整合实例--学生查询

    一.快速准备 SSM 框架即 Spring 框架.SpringMVC 框架.MyBatis 框架,关于这几个框架的基础和入门程序,我前面已经写过几篇文章作为基础和入门介绍了.对于这 3 个框架还不熟悉 ...