题目大意:

有边权点权的树,动态修改点权

每次修改后求带权重心x (\(minimize\) \(S=\sum_i val[i]*dist[x][i]\))

分析:

从暴力找突破口:

对于边x,y,设长度为len,切断后x半边树权值和为\(w_1\),y半边树为\(w_2\)

若从重心从x转到到y,则\(S+w_1*len-w_2*len\)

y比x优当且仅当\(w_2>w_1\)

设当前根为root,若root的一儿子x,满足\(w_x>w_{root}-w_x\),则x更优,且可以证明\(w_x>\frac {w_{root}} 2\),即不会存在第二个儿子y也比root优

做法:

暴力做法深度无保证,但\(w_x>w_{root}-w_x\)可以确定答案在x子树

我们用点分治树保证深度

新的问题:点分治树怎么求w

对于边x,y,设x半边树中所有点到x距离为\(d_1\),y半边树中所有点到y距离为\(d_2\)

所有点到x距离为\(d_1+d_2+w_2*len\)

所有点到y距离为\(d_1+d_2+w_1*len\)

可以了啊,这就是动态点分治模板了

询问复杂度\(nlog^2n\)

后来信息队一位善于创新的大神想到了nlogn的方法

x为rt,y为点分儿子时

x在上则两边权值和分别为w(y)和w(root)-w(y)

y在上则两边权值和分别为w(root)-w(x)+w(y)和w(x)-w(y)

乍一看非常正确,用rmq求个lca就可以O(1)判上下,超简便维护

但如果如图 :



兜来兜去的图发现bug多多

吸取经验

  1. #include <cstdio>
  2. #include <cstdlib>
  3. #include <cstring>
  4. #include <algorithm>
  5. #include <cmath>
  6. #include <cctype>
  7. using namespace std;
  8. typedef long long LL;
  9. const int M=100007;
  10. const int N=M*20*2;
  11. inline int rd(){
  12. int x=0;bool f=1;char c=getchar();
  13. for(;!isdigit(c);c=getchar())if(c=='-')f=0;
  14. for(;isdigit(c);c=getchar())x=x*10+c-48;
  15. return f?x:-x;
  16. }
  17. int n,m;
  18. int g[M],te;
  19. struct edge{
  20. int y,next;
  21. LL d;
  22. }e[M<<1];
  23. void addedge(int x,int y,LL d){
  24. e[++te].y=y;
  25. e[te].d=d;
  26. e[te].next=g[x];
  27. g[x]=te;
  28. }
  29. int fir[M],td;
  30. struct down{
  31. int y;//点分儿子
  32. int son;//亲儿子
  33. int next;
  34. }dw[M];
  35. void adddw(int x,int y,int son){
  36. dw[++td].y=y;
  37. dw[td].son=son;
  38. dw[td].next=fir[x];
  39. fir[x]=td;
  40. }
  41. int hd[M],tu;
  42. struct uppp{
  43. int all,sub,next;
  44. LL dis;
  45. }up[N];
  46. void addup(int x,int all,int sub,LL dis){
  47. up[++tu].all=all;
  48. up[tu].sub=sub;
  49. up[tu].dis=dis;
  50. up[tu].next=hd[x];
  51. hd[x]=tu;
  52. }
  53. struct node{
  54. LL sum,val;
  55. }a[M<<1];
  56. int idrt,idsub,nw;
  57. int sz[M],vis[M];
  58. int mi,size,rt,root;
  59. void getsz(int x,int fa){
  60. sz[x]=1;
  61. int p,y;
  62. for(p=g[x];p;p=e[p].next)
  63. if(!vis[y=e[p].y]&&y!=fa){
  64. getsz(y,x);
  65. sz[x]+=sz[y];
  66. }
  67. }
  68. void getrt(int x,int fa){
  69. int f,p,y;
  70. f=size-sz[x];
  71. for(p=g[x];p;p=e[p].next)
  72. if(!vis[y=e[p].y]&&y!=fa){
  73. getrt(y,x);
  74. f=max(f,sz[y]);
  75. }
  76. if(f<mi) mi=f,rt=x;
  77. }
  78. void dfs(int x,int fa,LL dis){
  79. addup(x,idrt,idsub,dis);
  80. int p,y;
  81. for(p=g[x];p;p=e[p].next)
  82. if(!vis[y=e[p].y]&&y!=fa){
  83. dfs(y,x,dis+e[p].d);
  84. }
  85. }
  86. void work(int frm,int drt){
  87. getsz(frm,0);
  88. mi=size=sz[frm];
  89. getrt(frm,0);
  90. int x=rt,p,y;
  91. vis[x]=1;
  92. idrt=++nw;
  93. addup(x,idrt,-1,0);
  94. if(drt) adddw(drt,x,frm);
  95. else root=x;
  96. for(p=g[x];p;p=e[p].next)
  97. if(!vis[y=e[p].y]){
  98. idsub=++nw;
  99. dfs(y,x,e[p].d);
  100. }
  101. for(p=g[x];p;p=e[p].next)
  102. if(!vis[y=e[p].y]) work(y,x);
  103. }
  104. void update(int x,LL y){
  105. int p;
  106. for(p=hd[x];p;p=up[p].next){
  107. a[up[p].all].val+=y;
  108. a[up[p].all].sum+=y*up[p].dis;
  109. if(up[p].sub!=-1){
  110. a[up[p].sub].val+=y;
  111. a[up[p].sub].sum+=y*up[p].dis;
  112. }
  113. }
  114. }
  115. LL get(int x){
  116. LL res=0;
  117. int p;
  118. for(p=hd[x];p;p=up[p].next){
  119. res+=a[up[p].all].sum;
  120. res+=a[up[p].all].val*up[p].dis;
  121. if(up[p].sub!=-1){
  122. res-=a[up[p].sub].sum;
  123. res-=a[up[p].sub].val*up[p].dis;
  124. }
  125. }
  126. return res;
  127. }
  128. int anst;
  129. void find(int x){
  130. int p,y,bb=1;
  131. for(p=fir[x];p;p=dw[p].next)
  132. if(get(x)>=get(dw[p].son)){
  133. bb=0;
  134. find(dw[p].y);
  135. break;
  136. }
  137. if(bb) anst=x;
  138. }
  139. int main(){
  140. int i,x,y,z;
  141. n=rd();m=rd();
  142. for(i=1;i<n;i++){
  143. x=rd(),y=rd(),z=rd();
  144. addedge(x,y,z);
  145. addedge(y,x,z);
  146. }
  147. work(1,0);
  148. for(i=1;i<=m;i++){
  149. x=rd(),y=rd();
  150. update(x,y);
  151. find(root);
  152. printf("%lld\n",get(anst));
  153. }
  154. return 0;
  155. }

bzoj 3924 幻想乡战略游戏的更多相关文章

  1. bzoj 3924 幻想乡战略游戏 —— 动态点分治

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3924 参考了博客:https://blog.csdn.net/qq_34564984/art ...

  2. bzoj3924 [Zjoi2015]幻想乡战略游戏 点分树,动态点分

    [BZOJ3924][Zjoi2015]幻想乡战略游戏 Description 傲娇少女幽香正在玩一个非常有趣的战略类游戏,本来这个游戏的地图其实还不算太大,幽香还能管得过来,但是不知道为什么现在的网 ...

  3. 【BZOJ3924】幻想乡战略游戏(动态点分治)

    [BZOJ3924]幻想乡战略游戏(动态点分治) 题面 权限题...(穷死我了) 洛谷 题解 考虑不修改 发现一个贪心的做法 假设当前放在当前位置 如果它有一个子树的兵的总数大于总数的一半 那么,放到 ...

  4. LOJ2135 「ZJOI2015」幻想乡战略游戏

    题意 题目描述 傲娇少女幽香正在玩一个非常有趣的战略类游戏,本来这个游戏的地图其实还不算太大,幽香还能管得过来,但是不知道为什么现在的网游厂商把游戏的地图越做越大,以至于幽香一眼根本看不过来,更别说和 ...

  5. LOJ #2135. 「ZJOI2015」幻想乡战略游戏

    #2135. 「ZJOI2015」幻想乡战略游戏 链接 分析: 动态点分治,求加权重心,带修改. 考虑如果知道了一个点s,如何求答案,那么首先可以点分治的思想,求每个联通块内所有点到分治中心距离和,然 ...

  6. 洛谷 P3345 [ZJOI2015]幻想乡战略游戏 解题报告

    P3345 [ZJOI2015]幻想乡战略游戏 题目描述 傲娇少女幽香正在玩一个非常有趣的战略类游戏,本来这个游戏的地图其实还不算太大,幽香还能管得过来,但是不知道为什么现在的网游厂商把游戏的地图越做 ...

  7. [ZJOI2015]幻想乡战略游戏——动态点分治

    [ZJOI2015]幻想乡战略游戏 带修改下,边点都带权的重心 随着变动的过程中,一些子树内的点经过会经过一些公共边.考虑能不能对这样的子树一起统计. 把树上贡献分块. 考虑点分治算法 不妨先把题目简 ...

  8. BZOJ3924 ZJOI2015 幻想乡战略游戏 【动态点分治】

    BZOJ3924 ZJOI2015 幻想乡战略游戏 Description 傲娇少女幽香正在玩一个非常有趣的战略类游戏,本来这个游戏的地图其实还不算太大,幽香还能管得过来,但是不知道为什么现在的网游厂 ...

  9. AC日记——[ZJOI2015]幻想乡战略游戏 洛谷 P3345

    [ZJOI2015]幻想乡战略游戏 思路: 树剖暴力转移: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 1 ...

随机推荐

  1. 01_9_Struts用ModelDriven接收参数

    01_9_Struts用ModelDriven接收参数 1. 配置struts.xml文件 <package name="user" namespace="/use ...

  2. 字节跳动后端开发实习生面试(Python)

    一面: 1.自我介绍. 2.介绍“工大小美”项目相关. 3.Python中的GIL(全局解释器锁),以及哪种情况下使用python的多线程性能有较大的提升. 4.项目中用到了SQLite数据库,如果有 ...

  3. [LOJ] #2360. 「NOIP2016」换教室

    期望DP #include<iostream> #include<cstring> #include<cstdio> #include<cctype> ...

  4. Protobuf有没有比JSON快5倍?用代码来击破pb性能神话

    转 http://www.sohu.com/a/136487507_505779 2017-04-26 07:58 程序设计 /58 /技术 导读:Google 的 Protocol Buffers ...

  5. 转 消息队列之 RabbitMQ

    转 https://www.jianshu.com/p/79ca08116d57 消息队列之 RabbitMQ 预流 2017.05.06 16:03* 字数 4884 阅读 80990评论 18喜欢 ...

  6. python-matplotlib-lec0

    直奔主题吧..以下是对matplotlib画图的简单讲解,代码已测试. win7 + pycharm + python 2.7 参考文档: http://old.sebug.net/paper/boo ...

  7. $(MAKE) , make命令

    make 定义了很多默认变量,像常用的命令或者是命令选项之类的,什么CC啊,CFLAGS啊之类.$(MAKE)就是预设的 make 这个命令的名称(或者路径).make -p 可以查看所有预定义的变量 ...

  8. stm32之Cortex系统定时器(SysTick)

    转载自:http://www.21ic.com/app/mcu/201811/781135.htm   SysTick时钟,俗称“嘀嗒定时器”,它能按设定的时间产生一次中断.控制工程代码中随处可见形如 ...

  9. http请求原理

    客户端发送一个HTTP请求到服务器的请求消息包括以下格式:请求行(request line).请求头部(header).空行和请求数据四个部分组成,下图给出了请求报文的一般格式. 请求行 HTTP响应 ...

  10. LA 6538 Dinner Coming Soon DP

    题意: 给出一个有\(N\)个顶点\(M\)条有向边的图,起点为\(1\),终点为\(N\). 每条边有经过的时间,和经过这条边的花费.一开始你有\(R\)元钱,要在\(T\)时间内赶到终点去约会. ...