bzoj千题计划245:bzoj1095: [ZJOI2007]Hide 捉迷藏

时间:2022-02-01 02:21:07

http://www.lydsy.com/JudgeOnline/problem.php?id=1095

查询最远点对,带修改

显然可以用动态点分治

对于每个点,维护两个堆

堆q1[x] 维护 点分树x的子树中,所有黑点到x的点分树中父节点的距离

堆q2[x]维护 点分树x的子节点的堆q1的堆顶,即若y是x在点分树中的子节点,则q2[x].push(q1[y].top())

再来维护一个全局的堆Q,维护所有q2的堆顶,即Q.push(q2[x].top())

#include<cmath>
#include<queue>
#include<cstdio>
#include<iostream> using namespace std; #define N 100001 #define Swap(a,b) ( (a)^=(b),(b)^=(a),(a)^=(b) ) int n; int front[N],to[N<<],nxt[N<<],tot; int fa[N]; bool light[N];
int sum; void read(int &x)
{
x=; char c=getchar();
while(!isdigit(c)) c=getchar();
while(isdigit(c)) { x=x*+c-''; c=getchar(); }
} void add(int u,int v)
{
to[++tot]=v; nxt[tot]=front[u]; front[u]=tot;
to[++tot]=u; nxt[tot]=front[v]; front[v]=tot;
} namespace LCA
{
int fa[N][],dep[N],bin[],lim; void dfs(int x)
{
for(int i=front[x];i;i=nxt[i])
if(to[i]!=fa[x][])
{
dep[to[i]]=dep[x]+;
fa[to[i]][]=x;
dfs(to[i]);
}
} int query(int x,int y)
{
if(dep[x]<dep[y]) swap(x,y);
for(int i=lim;i>=;--i)
if(dep[fa[x][i]]>=dep[y]) x=fa[x][i];
if(x==y) return x;
for(int i=lim;i>=;--i)
if(fa[x][i]!=fa[y][i]) x=fa[x][i],y=fa[y][i];
return fa[x][];
} int dist(int x,int y)
{
return dep[x]+dep[y]-(dep[query(x,y)]<<);
} void main()
{
lim=log(n)/log();
bin[]=;
for(int i=;i<;++i) bin[i]=bin[i-]<<;
dep[]=;
dfs();
for(int i=;i<=lim;++i)
for(int j=;j<=n;++j)
fa[j][i]=fa[fa[j][i-]][i-];
}
} struct HEAP
{
priority_queue<int>heap,trash; void Pop(int x) { trash.push(x); } void Push(int x) { heap.push(x); } int Size() { return heap.size()-trash.size(); } int Top()
{
if(Size())
{
while(!trash.empty() && heap.top()==trash.top()) heap.pop(),trash.pop();
return heap.top();
}
return ;
} int Top_Sec()
{
if(Size()>=)
{
int first,second;
while(!trash.empty() && heap.top()==trash.top()) heap.pop(),trash.pop();
first=heap.top(); heap.pop();
while(!trash.empty() && heap.top()==trash.top()) heap.pop(),trash.pop();
second=heap.top(); heap.push(first);
return first+second;
}
else return Top();
} }q1[N],q2[N],Q; namespace Point_divide
{
int siz[N],mx[N];
bool vis[N]; int root,min_size; void get_dist(int x,int pa,int fa)
{
q1[root].Push(LCA::dist(pa,x));
for(int i=front[x];i;i=nxt[i])
if(to[i]!=fa && !vis[to[i]]) get_dist(to[i],pa,x);
} void get_size(int x,int fa)
{
siz[x]=; mx[x]=;
for(int i=front[x];i;i=nxt[i])
if(!vis[to[i]] && to[i]!=fa)
{
get_size(to[i],x);
siz[x]+=siz[to[i]];
if(siz[to[i]]>mx[x]) mx[x]=siz[to[i]];
}
} void get_root(int x,int pa,int fa)
{
mx[x]=max(mx[x],siz[pa]-siz[x]);
if(mx[x]<min_size) min_size=mx[x],root=x;
for(int i=front[x];i;i=nxt[i])
if(to[i]!=fa && !vis[to[i]]) get_root(to[i],pa,x);
} void work(int x,int pa)
{
min_size=n+;
get_size(x,);
get_root(x,x,);
fa[root]=pa;
vis[root]=true;
q2[root].Push();
q1[root].Push(LCA::dist(pa,root));
for(int i=front[root];i;i=nxt[i])
if(!vis[to[i]]) get_dist(to[i],pa,root);
q2[pa].Push(q1[root].Top());
int rt=root;
for(int i=front[root];i;i=nxt[i])
if(!vis[to[i]]) work(to[i],rt);
if(q2[rt].Size()>=) Q.Push(q2[rt].Top_Sec());
} void main()
{
work(,);
} } void turn_off(int x)
{
if(q2[x].Size()>=) Q.Pop(q2[x].Top_Sec());
q2[x].Push();
if(q2[x].Size()>=) Q.Push(q2[x].Top_Sec());
for(int u=x;fa[u];u=fa[u])
{
if(q2[fa[u]].Size()>=) Q.Pop(q2[fa[u]].Top_Sec());
if(q1[u].Size()) q2[fa[u]].Pop(q1[u].Top());
q1[u].Push(LCA::dist(fa[u],x));
q2[fa[u]].Push(q1[u].Top());
if(q2[fa[u]].Size()>=) Q.Push(q2[fa[u]].Top_Sec());
}
} void turn_on(int x)
{
if(q2[x].Size()>=) Q.Pop(q2[x].Top_Sec());
q2[x].Pop();
if(q2[x].Size()>=) Q.Push(q2[x].Top_Sec());
for(int u=x;fa[u];u=fa[u])
{
if(q2[fa[u]].Size()>=) Q.Pop(q2[fa[u]].Top_Sec());
q2[fa[u]].Pop(q1[u].Top());
q1[u].Pop(LCA::dist(x,fa[u]));
if(q1[u].Size()) q2[fa[u]].Push(q1[u].Top());
if(q2[fa[u]].Size()>=) Q.Push(q2[fa[u]].Top_Sec());
}
} int main()
{
//freopen("hide.in","r",stdin);
//freopen("hide.out","w",stdout);
read(n);
int u,v;
for(int i=;i<n;++i)
{
read(u); read(v);
add(u,v);
}
LCA::main();
Point_divide::main();
sum=n;
int m; char s[];
read(m);
// printf("%d\n",Q.Top());
while(m--)
{
scanf("%s",s);
if(s[]=='G')
{
if(sum>=) printf("%d\n",Q.Top());
else printf("%d\n",sum-);
}
else
{
read(u);
if(light[u])turn_off(u),sum++;
else turn_on(u),sum--;
light[u]^=;
//printf("%d\n",Q.Top());
}
}
return ;
}

bzoj千题计划245:bzoj1095: [ZJOI2007]Hide 捉迷藏的更多相关文章

  1. 动态点分治:Bzoj1095&colon; &lbrack;ZJOI2007&rsqb;Hide 捉迷藏

    简介 这是我自己的一点理解,可能写的不好 点分治都学过吧.. 点分治每次找重心把树重新按重心的深度重建成了一棵新的树,称为分治树 这个树最多有log层... 动态点分治:记录下每个重心的上一层重心,这 ...

  2. &lbrack;bzoj1095&rsqb;&lbrack;ZJOI2007&rsqb;Hide 捉迷藏 点分树,动态点分治

    [bzoj1095][ZJOI2007]Hide 捉迷藏 2015年4月20日7,8876 Description 捉迷藏 Jiajia和Wind是一对恩爱的夫妻,并且他们有很多孩子.某天,Jiaji ...

  3. bzoj千题计划300:bzoj4823&colon; &lbrack;Cqoi2017&rsqb;老C的方块

    http://www.lydsy.com/JudgeOnline/problem.php?id=4823 讨厌的形状就是四联通图 且左右各连一个方块 那么破坏所有满足条件的四联通就好了 按上图方式染色 ...

  4. bzoj千题计划252:bzoj1095&colon; &lbrack;ZJOI2007&rsqb;Hide 捉迷藏

    http://www.lydsy.com/JudgeOnline/problem.php?id=1095 点分树+堆 请去看 http://www.cnblogs.com/TheRoadToTheGo ...

  5. bzoj千题计划163:bzoj1060&colon; &lbrack;ZJOI2007&rsqb;时态同步

    http://www.lydsy.com/JudgeOnline/problem.php?id=1060 以激发器所在节点为根 终止节点一定是叶节点 记录点的子树内最深的终止节点 然后从根往下使用道具 ...

  6. bzoj千题计划196:bzoj4826&colon; &lbrack;Hnoi2017&rsqb;影魔

    http://www.lydsy.com/JudgeOnline/problem.php?id=4826 吐槽一下bzoj这道题的排版是真丑... 我还是粘洛谷的题面吧... 提供p1的攻击力:i,j ...

  7. bzoj千题计划280:bzoj4592&colon; &lbrack;Shoi2015&rsqb;脑洞治疗仪

    http://www.lydsy.com/JudgeOnline/problem.php?id=4592 注意操作1 先挖再补,就是补的范围可以包含挖的范围 SHOI2015 的题 略水啊(逃) #i ...

  8. bzoj千题计划177:bzoj1858&colon; &lbrack;Scoi2010&rsqb;序列操作

    http://www.lydsy.com/JudgeOnline/problem.php?id=1858 2018 自己写的第1题,一遍过 ^_^ 元旦快乐 #include<cstdio&gt ...

  9. bzoj千题计划317:bzoj4650&colon; &lbrack;Noi2016&rsqb;优秀的拆分(后缀数组&plus;差分)

    https://www.lydsy.com/JudgeOnline/problem.php?id=4650 如果能够预处理出 suf[i] 以i结尾的形式为AA的子串个数 pre[i] 以i开头的形式 ...

随机推荐

  1. webpack &plus; vuejs 基本配置(一)

    开始之前 本文包含以下技术,文中尽量给与详细的描述,并且附上参考链接,读者可以深入学习: 1.webpack2.Vue.js3.npm4.nodejs —- 这个就不给连接了,因为上面的连接都是在你实 ...

  2. mac系统如何关闭root账户

    第一步:系统偏好设置 ->用户与群组 第二步:登录选项 ->解锁 ->单击网络帐户服务器加入 第三步:打开目录实用工具 第四步:菜单栏 ->编辑 ->停用 Root 用户 ...

  3. 转载:Cocos2D-x 游戏接入 Windows 设备所需做的六件事

    原文地址:http://msopentech.com/zh-hans/blog/2014/05/09/cocos2d-x-%E6%B8%B8%E6%88%8F%E6%8E%A5%E5%85%A5-wi ...

  4. HDU 3047 Zjnu Stadium&lpar;带权并查集&rpar;

    题意:有一个环形体育场,有n个人坐,给出m个位置关系,A B x表示B所在的列在A的顺时针方向的第x个,在哪一行无所谓,因为假设行有无穷个. 给出的座位安排中可能有与前面矛盾的,求有矛盾冲突的个数. ...

  5. 火狐的打开3D效果

    最近研究网页的时候,想看看一个页面中盒子的层次问题,点击右键查看元素的后,没有发现3D效果的按钮. 在网上百度后说要什么显卡支持,以为是公司的电脑用的是集显,就没有这个功能.回去用自己的笔记本后,发现 ...

  6. Determining IP information for eth1&period;&period;&period; failed&semi; no link present&period; Check cable? 解决办法

    有时候会遇到这种问题 解决办法为 进入网卡配置,将 BOOTPROTO 改为 none 然后 ifconfig –a 查看可以得到 eth1 已经可以寻到 iP 地址,如下: Service netw ...

  7. 使用UDL文件来测试SQL Server数据库连接

    原文 来自http://www.2cto.com/database/201308/234427.html 使用UDL测试SQL Server连接问题   做数据库经常会遇到SQL Server连接的问 ...

  8. 学习笔记3-开发与运行&lpar;卸载&rpar;第一个ANDROID应用

    新建Android项目 1.      配置好Android坏境以后,新建项目选择Android Project. 2.      选择针对哪个平台开发的应用(Android2/Android4等) ...

  9. &lbrack;PHP&rsqb;命名空间的一些要点

    1.命名空间前不能接"\": namespace MyProject\Sub\Level; // it's right; namespace \MyProject\Sub\Leve ...

  10. &lt&semi;Spark&gt&semi;&lt&semi;Advanced Programming&gt&semi;

    Introduction 介绍两种共享变量的方式: accumulators:聚集信息 broadcast variables:高效地分布large values 介绍对高setup costs任务的 ...