好迷啊。。。感觉动态点分治就是个玄学,蜜汁把树的深度缩到logn

(静态)点分治大概是递归的时候分类讨论:

  1.答案经过当前点,暴力(雾)算

  2.答案不经过当前点,继续递归

由于原树可以长的奇形怪状(菊花啊、、链啊、、扫把啊、、)这就导致各种方法都会被卡

于是通过每次找重心保证最大深度

动态怎么解决呢?

不妨考虑线段树是二分的固态版本(只可意会),那么我们把每次找到的重心固定下来长成一棵树就可以把点分治凝固(不可言传)

原来点分治该维护什么现在就维护什么。。。

(事实上我并没有写过静态点分治。。。好气啊╮(╯▽╰)╭)

我居然一度认为新建的树的节点要连到所在子树外一定要经过该子树的根。。。太思博了

实现细节:

  1.有一个带删堆,直接拉了板子(拉了才知道实现那么简单,本来以为手打)

  2.lca以前习惯rmq(复杂度优异就是自信),现在改成倍增了(可能是之前写了个长链剖分的缘故)

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 const int Mn=100005;
  4 int cnt=0,h[Mn],n,m,vst[Mn],maxx,tg,s[Mn],sz,prt[Mn];
  5 int d[Mn],p[Mn][21],co[Mn];
  6 struct Priority_Queue{
  7     priority_queue<int> q,del;
  8     void push(int x)
  9     {q.push(x);}
 10     void erase(int x){del.push(x);}
 11     int top()
 12     {
 13         while(del.size()&&del.top()==q.top())
 14             {del.pop();q.pop();}
 15         return q.top();
 16     }
 17     void Pop()
 18     {
 19         while(del.size()&&del.top()==q.top())
 20             del.pop(),q.pop();
 21         q.pop();
 22     }
 23     int sec_top()
 24     {
 25         int tmp=top();Pop();
 26         int se=top();push(tmp);
 27         return se;
 28     }
 29     int size()
 30     {
 31         return q.size()-del.size();
 32     }
 33 }c[Mn],f[Mn],ans;
 34 struct Edge{int to,next;}w[Mn*2];
 35 void add(int x,int y)
 36 {w[++cnt]=(Edge){y,h[x]};h[x]=cnt;}
 37 void build(int x,int fa)
 38 {
 39     p[x][0]=fa;d[x]=d[fa]+1;
 40     for(int i=1;p[x][i-1];i++)
 41         p[x][i]=p[p[x][i-1]][i-1];
 42     for(int i=h[x];i;i=w[i].next)
 43     if(w[i].to!=fa)
 44         build(w[i].to,x);
 45 }
 46 void Insert(Priority_Queue &s){
 47      if(s.size()>1)ans.push(s.top()+s.sec_top());
 48 }
 49 void Erase(Priority_Queue &s){
 50      if(s.size()>1)ans.erase(s.top()+s.sec_top());
 51 }
 52 void DP(int x,int fa)
 53 {
 54      int j,y;s[x]=1;
 55      for(j=h[x];j;j=w[j].next)
 56      {
 57         y=w[j].to;
 58         if(y==fa||vst[y])continue;
 59         DP(y,x);
 60         s[x]+=s[y];
 61      }
 62 }
 63 void Biggest(int x,int fa){
 64      int j,y,mx=0;
 65      for(j=h[x];j;j=w[j].next){
 66         y=w[j].to;
 67         if(y==fa||vst[y])continue;
 68         Biggest(y,x);
 69         mx=max(mx,s[y]);
 70      }
 71      if(maxx>max(mx,sz-s[x])){
 72         maxx=max(mx,sz-s[x]);
 73         tg=x;
 74      }
 75 }
 76 int gg(int x)//get G
 77 {
 78     maxx=n+1;tg=0;
 79     DP(x,0);
 80     sz=s[x];
 81     Biggest(x,0);
 82     return tg;
 83 }
 84 int LCA(int x,int y){
 85     int j;
 86     if(d[x]<d[y])swap(x,y);
 87     for(j=20;j>=0;j--)
 88       if(d[p[x][j]]>=d[y])x=p[x][j];
 89     if(x==y)return x;
 90     for(j=20;j>=0;j--)
 91       if(p[x][j]!=p[y][j])
 92        {x=p[x][j];y=p[y][j];}
 93     return p[x][0];
 94 }
 95 int Dis(int x,int y){return d[x]+d[y]-2*d[LCA(x,y)];}
 96 void work(int x,int fa,int Gra){
 97      int j,y;
 98      f[Gra].push(Dis(x,prt[Gra]));
 99      for(j=h[x];j;j=w[j].next){
100         y=w[j].to;
101         if(y==fa||vst[y])continue;
102         work(y,x,Gra);
103      }
104 }
105 int mzz(int x,int fa)
106 {
107     int j,y,G,Gy;
108     G=gg(x);prt[G]=fa;
109     work(G,0,G);
110     vst[G]=1;
111     c[G].push(0);
112     for(j=h[G];j;j=w[j].next)
113     {
114         y=w[j].to;
115         if(!vst[y]){
116             Gy=mzz(y,G);
117             c[G].push(f[Gy].top());
118         }
119     }
120     Insert(c[G]);
121     return G;
122 }
123 void Light(int x){
124      Erase(c[x]);
125      c[x].erase(0);
126      Insert(c[x]);
127      for(int y=x;prt[y];y=prt[y]){
128         Erase(c[prt[y]]);
129         if(f[y].size())c[prt[y]].erase(f[y].top());
130         f[y].erase(Dis(x,prt[y]));
131         if(f[y].size())c[prt[y]].push(f[y].top());
132         Insert(c[prt[y]]);
133      }
134 }
135 void LiOut(int x){
136      Erase(c[x]);
137      c[x].push(0);
138      Insert(c[x]);
139      for(int y=x;prt[y];y=prt[y]){
140         Erase(c[prt[y]]);
141         if(f[y].size())c[prt[y]].erase(f[y].top());
142         f[y].push(Dis(x,prt[y]));
143         if(f[y].size())c[prt[y]].push(f[y].top());
144         Insert(c[prt[y]]);
145      }
146 }
147 void solve(){
148      int i,x;char ch[5];
149      cnt=n;
150      scanf("%d",&m);
151      for(i=1;i<=m;i++){
152         scanf("%s",ch);
153         if(ch[0]=='G'){
154           if(cnt<=1)printf("%d\n",cnt-1);
155           else printf("%d\n",ans.top());
156         }
157         else{
158             scanf("%d",&x);
159             if(!co[x]){cnt--;Light(x);co[x]=1;}
160             else{cnt++;LiOut(x);co[x]=0;}
161         }
162      }
163 }
164 int main()
165 {
166     scanf("%d",&n);int x,y;
167     for(int i=1;i<n;i++)
168         scanf("%d%d",&x,&y),
169         add(x,y),add(y,x);
170     build(1,0);mzz(1,0);
171     solve();
172     return 0;
173 }  

转载于:https://www.cnblogs.com/wanglichao/p/6885797.html

bzoj1095: [ZJOI2007]Hide 捉迷藏 动态点分治学习相关推荐

  1. BZOJ1095: [ZJOI2007]Hide 捉迷藏(动态点分治)

    Description 捉迷藏 Jiajia和Wind是一对恩爱的夫妻,并且他们有很多孩子.某天,Jiajia.Wind和孩子们决定在家里玩 捉迷藏游戏.他们的家很大且构造很奇特,由N个屋子和N-1条 ...

  2. BZOJ1095 ZJOI2007 Hide 捉迷藏

    BZOJ1095 ZJOI2007 Hide 捉迷藏 动态树分治+堆 动态点分治 posted on 2016-06-25 11:35  wjyi 阅读( ...) 评论( ...) 编辑 收藏 转载 ...

  3. BZOJ1095 [ZJOI2007]Hide 捉迷藏 【动态点分治 + 堆】

    题目链接 BZOJ1095 题解 传说中的动态点分治,一直不敢碰 今日一会,感觉其实并不艰涩难懂 考虑没有修改,如果不用树形dp的话,就得点分治 对于每个重心,我们会考虑其分治的子树内所有点到它的距离 ...

  4. bzoj1095: [ZJOI2007]Hide 捉迷藏

    题目链接 bzoj1095 题意 Description 捉迷藏 Jiajia和Wind是一对恩爱的夫妻,并且他们有很多孩子.某天,Jiajia.Wind和孩子们决定在家里玩捉迷藏游戏.他们的家很大且 ...

  5. bzoj1095: [ZJOI2007]Hide 捉迷藏 线段树维护括号序列 点分治 链分治

    这题真是十分难写啊 不管是点分治还是括号序列都有一堆细节.. 点分治:时空复杂度$O(n\log^2n)$,常数巨大 主要就是3个堆的初始状态 C堆:每个节点一个,为子树中的点到它父亲的距离的堆. B ...

  6. bzoj1095 [ZJOI2007]Hide 捉迷藏

    据说是道很厉害的题....黄学长的安利啊.... 然而我却用它学分治.... 一个坑就摆在这里了.... 转载于:https://www.cnblogs.com/LLppdd/p/9124394.ht ...

  7. 【BZOJ 1095】 1095: [ZJOI2007]Hide 捉迷藏 (括号序列+线段树)

    1095: [ZJOI2007]Hide 捉迷藏 Description 捉迷藏 Jiajia和Wind是一对恩爱的夫妻,并且他们有很多孩子.某天,Jiajia.Wind和孩子们决定在家里玩 捉迷藏游 ...

  8. [ZJOI2007]Hide 捉迷藏

    [ZJOI2007]Hide 捉迷藏 小岛的博客 黄学长的博客 NOI08 冬令营论文 <数据结构的提炼与压缩> 这个问题竟然还能用线段树做,拿小本本记下来. 转载于:https://ww ...

  9. BZOJ1095 [ZJOI2007]捉迷藏 动态点分治

    每次修改一个点的黑白状态,询问树上最远黑点距离 拿这个题做动态点分治模板题:(%%%PoPoQQQ大爷) 点分治的过程是对树块找重心之后分成多个小树块,降低规模分别处理的过程,把链的信息收到其中&qu ...

最新文章

  1. 看微软如何发展 Windows 下一代系统
  2. Hive中文注释乱码解决方案
  3. package.json、tsconfig.json、node_modules
  4. php网站调试出现的简单问题,调试php时网站出现502的解决方法
  5. Lucene实战之初体验
  6. 国内厂商 Onyx 违反 GPL 协议,中国开源何去何从?
  7. Java JDBC spring-jdbc
  8. 深度学习笔记(三)——GAN入门实现MNIST数据集
  9. 线程的同步互斥之事件对象(Event)
  10. 使用禅道管理项目流程
  11. 浪潮财务软件遇到问题
  12. JMeter下载安装以及使用教程
  13. 英语语法高考英语单词拼写必背全表
  14. ffmpeg时间戳计算
  15. FC/NES PPU 示例汇编程序 简易画图
  16. 电子计算机的产品情况,广东省市场监督管理局关于2020年度广东省电子计算机配套产品及耗材产品质量监督抽查情况的通告...
  17. 史上最亮眼成绩!中芯国际14nm工艺终于爆发了
  18. golang原生库mime/multipart上传formdata文件的一个小坑unexpected EOF
  19. 流量互点PHP源码,点击量软件-求一个网页可以增加流量的软件?要释放。 。 。自由...
  20. 激光SLAM源码解析S-LOAM(二)激光里程计的计算

热门文章

  1. java byte 循环左移 循环右移 rotateLeft rotateRight
  2. [多级联动下拉选择框]和[Tree to Tree]续——让他们可以设置默认值
  3. 也许是被忽略的update语句
  4. jQuery中HTML的操作
  5. 业界 | 李彦宏:中国人愿意用隐私交换便利性;无人车事故是“人咬狗”新闻...
  6. Linux Guide for Developers --- ubuntu开发者
  7. jquery.mobile手机网页简要
  8. GVRP和VTP比较
  9. 【BATJ面试必会】Java 基础篇
  10. 第4章 玩转数学公式