题目链接

BZOJ4012

题解

Mychael并没有A掉,而是T掉了

讲讲主要思路

在点分树上每个点开两棵\(splay\),

平衡树\(A\)维护子树中各年龄到根的距离

平衡树\(B\)维护子树中各年龄到点分树父亲的距离

然后询问就可以在点分树上用两棵平衡树相减计算了

大常数\(O(nlog^2n)\)被卡死

  1. // luogu-judger-enable-o2
  2. #include<algorithm>
  3. #include<iostream>
  4. #include<cstring>
  5. #include<cstdio>
  6. #include<cmath>
  7. #include<map>
  8. #define Redge(u) for (register int k = h[u],to; k; k = ed[k].nxt)
  9. #define REP(i,n) for (register int i = 1; i <= (n); i++)
  10. #define mp(a,b) make_pair<int,LL>(a,b)
  11. #define cls(s) memset(s,0,sizeof(s))
  12. #define cp pair<int,LL>
  13. #define LL long long int
  14. #define ls ch[u][0]
  15. #define rs ch[u][1]
  16. #define isr(u) (fa[u] && ch[fa[u]][1] == u)
  17. #define res register
  18. using namespace std;
  19. const int maxn = 200005,maxm = 10000005,INF = 1000000000;
  20. inline int read(){
  21. res int out = 0,flag = 1; res char c = getchar();
  22. while (c < 48 || c > 57){if (c == '-') flag = -1; c = getchar();}
  23. while (c >= 48 && c <= 57){out = (out << 3) + (out << 1) + c - 48; c = getchar();}
  24. return out * flag;
  25. }
  26. inline void write(LL x){
  27. if (x / 10) write(x / 10);
  28. putchar(x % 10 + '0');
  29. }
  30. int Siz[maxm],siz[maxm],w[maxm],ch[maxm][2],fa[maxm],cnt;
  31. LL Sum[maxm],sum[maxm];
  32. struct Splay_Tree{
  33. int rt;
  34. void upd(int u){
  35. Siz[u] = Siz[ls] + Siz[rs] + siz[u];
  36. Sum[u] = Sum[ls] + Sum[rs] + sum[u];
  37. }
  38. void spin(int u){
  39. int s = isr(u),f = fa[u];
  40. fa[u] = fa[f]; if (fa[f]) ch[fa[f]][isr(f)] = u;
  41. ch[f][s] = ch[u][s ^ 1]; if (ch[u][s ^ 1]) fa[ch[u][s ^ 1]] = f;
  42. fa[f] = u; ch[u][s ^ 1] = f;
  43. upd(f); upd(u);
  44. }
  45. void splay(int u,int f = 0){
  46. for (; fa[u] != f; spin(u))
  47. if (fa[fa[u]] != f) spin((isr(u) ^ isr(fa[u])) ? u : fa[u]);
  48. if (!f) rt = u;
  49. }
  50. void insert(int& u,int f,int v,int Val){
  51. if (!u){
  52. w[u = ++cnt] = v; Sum[u] = sum[u] = Val;
  53. fa[u] = f; siz[u] = Siz[u] = 1; splay(u);
  54. }
  55. else if (w[u] > v) insert(ls,u,v,Val);
  56. else if (w[u] < v) insert(rs,u,v,Val);
  57. else {Sum[u] += Val; sum[u] += Val; Siz[u]++; siz[u]++; splay(u);}
  58. }
  59. void ins(int pos,int v){insert(rt,0,pos,v);}
  60. int pre(int u,int v){
  61. if (!u) return 0;
  62. if (w[u] >= v) return pre(ls,v);
  63. else {
  64. int t = pre(rs,v);
  65. return t ? t : u;
  66. }
  67. }
  68. int post(int u,int v){
  69. if (!u) return 0;
  70. if (w[u] <= v) return post(rs,v);
  71. else {
  72. int t = post(ls,v);
  73. return t ? t : u;
  74. }
  75. }
  76. cp query(int l,int r){
  77. int L = pre(rt,l),R = post(rt,r);
  78. splay(L); splay(R,L);
  79. if (!ch[R][0]) return mp(0,0);
  80. return mp(Siz[ch[R][0]],Sum[ch[R][0]]);
  81. }
  82. void init(){rt = 0; ins(-INF,0); ins(INF,0);}
  83. }A[maxn],B[maxn];
  84. LL ans;
  85. int n,m,Limit,val[maxn],L,R;
  86. int h[maxn],ne = 1;
  87. struct EDGE{int to,nxt,w;}ed[maxn << 1];
  88. inline void build(int u,int v,int w){
  89. ed[++ne] = (EDGE){v,h[u],w}; h[u] = ne;
  90. ed[++ne] = (EDGE){u,h[v],w}; h[v] = ne;
  91. }
  92. LL Dis[maxn][23];
  93. int F[maxn],Fa[maxn],size[maxn],vis[maxn],N,rt;
  94. void getrt(int u){
  95. F[u] = 0; size[u] = 1;
  96. Redge(u) if (!vis[to = ed[k].to] && to != Fa[u]){
  97. Fa[to] = u; getrt(to);
  98. size[u] += size[to];
  99. F[u] = max(F[u],size[to]);
  100. }
  101. F[u] = max(F[u],N - size[u]);
  102. if (F[u] < F[rt]) rt = u;
  103. }
  104. int c[maxn],d[maxn],ci;
  105. void dfs1(int u){
  106. size[u] = 1; c[++ci] = u;
  107. Redge(u) if (!vis[to = ed[k].to] && to != Fa[u]){
  108. Fa[to] = u; d[to] = d[u] + ed[k].w;
  109. dfs1(to);
  110. size[u] += size[to];
  111. }
  112. }
  113. int pre[maxn],dep[maxn];
  114. void solve(int u,int D){
  115. vis[u] = true; size[u] = 1; ci = 0; d[u] = 0; dep[u] = D;
  116. A[u].init(); A[u].ins(val[u],0); B[u].init();
  117. Redge(u) if (!vis[to = ed[k].to]){
  118. Fa[to] = u; d[to] = d[u] + ed[k].w;
  119. dfs1(to);
  120. }
  121. int v = pre[u];
  122. REP(i,ci){
  123. A[u].ins(val[c[i]],d[c[i]]);
  124. Dis[c[i]][D] = d[c[i]];
  125. }
  126. if (v){
  127. B[u].ins(val[u],Dis[u][D - 1]);
  128. REP(i,ci) B[u].ins(val[c[i]],Dis[c[i]][D - 1]);
  129. }
  130. Redge(u) if (!vis[to = ed[k].to]){
  131. N = size[to]; F[rt = 0] = INF;
  132. getrt(to); pre[rt] = u;
  133. solve(rt,D + 1);
  134. }
  135. }
  136. void work(int x){
  137. ans = A[x].query(L,R).second;
  138. LL dd; cp t1,t2;
  139. for (res int u = x,i = dep[x] - 1; pre[u]; u = pre[u],i--){
  140. dd = Dis[x][i];
  141. t1 = A[pre[u]].query(L,R);
  142. t2 = B[u].query(L,R);
  143. ans += t1.second - t2.second + dd * (t1.first - t2.first);
  144. }
  145. printf("%lld\n",ans);
  146. }
  147. int main(){
  148. n = read(); m = read(); Limit = read();
  149. LL a,b,w;
  150. for (res int i = 1; i <= n; i++) val[i] = read();
  151. for (res int i = 1; i < n; i++){
  152. a = read(); b = read(); w = read();
  153. build(a,b,w);
  154. }
  155. N = n; F[rt = 0] = INF;
  156. getrt(1);
  157. solve(rt,0);
  158. int u;
  159. while (m--){
  160. u = read(); a = read(); b = read();
  161. L = (a + ans) % Limit;
  162. R = (b + ans) % Limit;
  163. if (L > R) swap(L,R);
  164. work(u);
  165. }
  166. return 0;
  167. }

BZOJ4012 [HNOI2015]开店 【动态点分治 + splay】的更多相关文章

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

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

  2. 【bzoj4012】[HNOI2015]开店 动态点分治+STL-vector

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

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

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

  4. P3241 [HNOI2015]开店 动态点分治

    \(\color{#0066ff}{ 题目描述 }\) 风见幽香有一个好朋友叫八云紫,她们经常一起看星星看月亮从诗词歌赋谈到人生哲学.最近她们灵机一动,打算在幻想乡开一家小店来做生意赚点钱. 这样的想 ...

  5. luogu 3241 [HNOI2015]开店 动态点分治+二分+vector

    独立写出来+想出来的,1.5h就切了~ 建立点分树,然后用 $vector$ 暴力存所有子节点,然后二分一下子就可以了. #include <cstdio> #include <ve ...

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

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

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

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

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

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

  9. [loj2116]「HNOI2015」开店 动态点分治

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

  10. BZOJ4012 [HNOI2015]开店

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

随机推荐

  1. JDK7 新特性

    JDK7新特性的目录导航: 二进制字面值 switch 语句支持 String try-with-resources catch 多个类型异常 字面值中使用下划线 类型推断 改进泛型类型可变参数 其它 ...

  2. python中协程实现的本质以及两个封装协程模块greenle、gevent

    协程 协程,又称微线程,纤程.英文名Coroutine. 协程是啥 协程是python个中另外一种实现多任务的方式,只不过比线程更小占用更小执行单元(理解为需要的资源). 为啥说它是一个执行单元,因为 ...

  3. SQL Server附加数据库拒绝访问错误解决方法

    今天在MsSQL里附加数据库时提示操作系统错误5(拒绝访问),这里我没给出了两个解决方案供大家解决问题. 方案一:切换登录方式 出现这种情况是由于用“混合验证方式”(SQL Server身份验证)登录 ...

  4. Java技术——I/O知识学习

    个字节,主要用在处理二进制数据,字节用来与文件打交道,所有文件的储存都是通过字节(byte)的方式,在磁盘上保留的并不是文件的字符而是先把字符编码成字节,再储存这些字节到磁盘.在读取文件(特别是文本文 ...

  5. 高德API+.NET解决租房问题(JS相关)

    在线地址:58同城品牌公寓高德搜房 Github地址:https://github.com/liguobao/58HouseSearch 知乎专栏(点赞用的):高德API+Python解决租房问题(. ...

  6. shell -- for、while用法

    #数字段形式for i in {1..10}do   echo $idone #详细列出(字符且项数不多)for File in 1 2 3 4 5do    echo $Filedone #对存在的 ...

  7. https 通信流程和Charles 抓包原理

    1. https 通信流程 ①客户端的浏览器向服务器传送客户端SSL 协议的版本号,加密算法的种类,产生的随机数,以及其他服务器和客户端之间通讯所需要的各种信息.②服务器向客户端传送SSL 协议的版本 ...

  8. C++重载赋值操作符

    1.C++中重载赋值操作函数应该返回什么? 类重载赋值操作符一般都是作为成员函数而存在的,那函数应该返回什么类型呢?参考内置类型的赋值操作,例如 int x,y,z; x=y=z=15; 赋值行为相当 ...

  9. 【廖雪峰老师python教程】——map/reduce

    Map[单个操作对不同单一对象重复进行] map()函数接收两个参数,一个是函数,一个是Iterable,map将传入的函数依次作用到序列的每个元素,并把结果作为新的Iterator返回. 返回结果注 ...

  10. Appium如何获取appPackage和appActivity

    基本概念: appPackage:简单来说是App开发者提供的名称. appActivity:简单来说是App提供的各种不同的功能.每个程序都有个MainActivity,就是打开程序时显示在屏幕的活 ...