[题目链接]

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

[算法]

首先建出点分树,然后每一个点开两个堆。“第一个堆记录子树中所有节点到父亲节点的距离 ,第二个堆记录所有子节点的堆顶 ,那么一个节点的堆2中的最大和次大加起来就是子树中经过这个节点的最长链。然后我们最后开一个全局的堆,记录所有堆2中最大值和次大值之和。那么全局的堆顶就是答

时间复杂度 : O(NlogN ^ 2)

[代码]

#include<bits/stdc++.h>
using namespace std;
#define N 100010
#define M 500010
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull; int n , root , tot , timer;
int size[N] , head[N] , weight[N] , father[N] , ans[N];
bool visited[N] , light[N];
map< int , pair<int , int> > mp[N]; struct edge
{
int to , nxt;
} e[M << ]; struct Heap
{
priority_queue< int > hp , era;
inline void ins(int value)
{
hp.push(value);
}
inline void del(int value)
{
if (value != ) era.push(value);
}
inline int max()
{
while (!hp.empty() && !era.empty() && era.top() == hp.top())
{
hp.pop();
era.pop();
}
if (hp.empty()) return ;
else return hp.top();
}
inline int secmax()
{
int tmp = max();
del(tmp);
int ret = max();
ins(tmp);
return ret;
}
} A , B[N] , C[N << ]; template <typename T> inline void chkmax(T &x,T y) { x = max(x,y); }
template <typename T> inline void chkmin(T &x,T y) { x = min(x,y); }
template <typename T> inline void read(T &x)
{
T f = ; x = ;
char c = getchar();
for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
for (; isdigit(c); c = getchar()) x = (x << ) + (x << ) + c - '';
x *= f;
}
inline void addedge(int u , int v)
{
++tot;
e[tot] = (edge){v , head[u]};
head[u] = tot;
}
inline void getroot(int u , int father , int total)
{
size[u] = ;
weight[u] = ;
for (int i = head[u]; i; i = e[i].nxt)
{
int v = e[i].to;
if (v == father || visited[v]) continue;
getroot(v , u , total);
size[u] += size[v];
chkmax(weight[u] , size[v]);
}
chkmax(weight[u] , total - size[u]);
if (weight[u] < weight[root]) root = u;
}
inline void dfs(int u , int father , int rt , int belong , int depth)
{
mp[rt][u] = make_pair(belong , depth);
C[belong].ins(depth);
for (int i = head[u]; i; i = e[i].nxt)
{
int v = e[i].to;
if (v == father || visited[v]) continue;
dfs(v , u , rt , belong , depth + );
}
}
inline void work(int u)
{
visited[u] = true;
for (int i = head[u]; i; i = e[i].nxt)
{
int v = e[i].to;
if (!visited[v])
{
dfs(v , u , u , ++timer , );
B[u].ins(C[timer].max());
}
}
ans[u] = B[u].max() + B[u].secmax();
A.ins(ans[u]);
for (int i = head[u]; i; i = e[i].nxt)
{
int v = e[i].to;
if (!visited[v])
{
root = ;
getroot(v , u , size[v]);
father[root] = u;
work(root);
}
}
} int main()
{ read(n);
for (int i = ; i < n; i++)
{
int x , y;
read(x); read(y);
addedge(x , y);
addedge(y , x);
}
int q;
read(q);
root = ;
weight[] = n;
getroot( , , n);
work(root);
int cnt = n;
while (q--)
{
char type[];
scanf("%s" , type);
if (type[] == 'C')
{
int x , y;
scanf("%d" , &x);
y = x;
if (light[x])
{
light[x] = false;
++cnt;
A.del(ans[x]);
ans[x] = B[x].max() + B[x].secmax();
A.ins(ans[x]);
x = father[x];
while (x != )
{
pair<int , int> tmp = mp[x][y];
B[x].del(C[tmp.first].max());
C[tmp.first].ins(tmp.second);
B[x].ins(C[tmp.first].max());
A.del(ans[x]);
if (light[x])
{
if (B[x].secmax()) ans[x] = B[x].max() + B[x].secmax();
else ans[x] = ;
} else ans[x] = B[x].max() + B[x].secmax();
A.ins(ans[x]);
x = father[x];
}
} else
{
light[x] = true;
--cnt;
A.del(ans[x]);
if (B[x].secmax()) ans[x] = B[x].max() + B[x].secmax();
else ans[x] = ;
A.ins(ans[x]);
x = father[x];
while (x != )
{
pair<int , int> tmp = mp[x][y];
B[x].del(C[tmp.first].max());
C[tmp.first].del(tmp.second);
B[x].ins(C[tmp.first].max());
A.del(ans[x]);
if (light[x])
{
if (B[x].secmax()) ans[x] = B[x].max() + B[x].secmax();
else ans[x] = ;
} else ans[x] = B[x].max() + B[x].secmax();
A.ins(ans[x]);
x = father[x];
}
}
} else
{
if (!cnt) printf("-1\n");
else if (cnt == ) printf("0\n");
else printf("%d\n" , A.max());
}
}
return ; }

[ZJOI 2007] 捉迷藏的更多相关文章

  1. 数据结构(括号序列,线段树||点分治,堆):ZJOI 2007 捉迷藏

    [题目描述] Jiajia和Wind是一对恩爱的夫妻,并且他们有很多孩子.某天,Jiajia.Wind和孩子们决定在家里玩捉迷藏游戏.他们的家很大且构造很奇特,由N个屋子和N-1条双向走廊组成,这N- ...

  2. [BZOJ 1095] [ZJOI 2007] 捉迷藏

    Description 传送门 Solution 先将原树转化成点分树: 然后维护三个堆: \(c[i]\) 保存点分树中子树 \(i\) 中的黑色节点到 \(fa[i]\) 的距离: \(b[i]\ ...

  3. [ZJOI 2007]Hide 捉迷藏

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

  4. [BZOJ 1095] [ZJOI 2007]Hide 捉迷藏

    在BZ上连续MLE n次后,终于A了. 自己YY的动态点分写法,思路还是很清楚的,但是比较卡内存. 用到了MAP导致复杂度比其他的代码多了一个log,看来需要去借鉴一下别人怎么写的. updata i ...

  5. 【BZOJ 1096】【ZJOI 2007】仓库建设 DP+斜率优化

    后缀自动机看不懂啊QAQ 放弃了还是看点更有用的东西吧,比如斜率优化DP 先水一道 #include<cstdio> #include<cstring> #include< ...

  6. [BZOJ 1058][ZJOI 2007]报表统计 平衡树+线段树

    考试的时候看见这道题,感觉自己能AC掉,然后就冲着正解去了.然后想了想数据结构,应该是平衡树.然而蒟蒻的我忘了平衡树怎么打了..然后就根据自己的记忆和理解打了出来.然后我简单的以为相邻的用个链表就能解 ...

  7. [ZJOI 2007]时态同步

    Description 小Q在电子工艺实习课上学习焊接电路板.一块电路板由若干个元件组成,我们不妨称之为节点,并将其用数字1,2,3….进行标号.电路板的各个节点由若干不相交的导线相连接,且对于电路板 ...

  8. [ZJOI 2007] 矩阵游戏

    [题目链接] https://www.lydsy.com/JudgeOnline/problem.php?id=1059 [算法] 二分图最大匹配 时间复杂度 : O(N^3) [代码] #inclu ...

  9. 洛谷 P1131 [ ZJOI 2007 ] 时态同步 —— 树形DP

    题目:https://www.luogu.org/problemnew/show/P1131 记录 x 子树内同步的时间 f[x],同步所需代价 g[x]: 直接转移即可,让该儿子子树与其它儿子同步, ...

随机推荐

  1. vue Syntax Error: Unexpected token {

    > music@1.0.0 dev F:\music\music> node build/dev-server.js > Starting dev server...ERROR Fa ...

  2. 安装 - LNMP一键安装包

    https://lnmp.org/ 系统需求: CentOS/RHEL/Fedora/Debian/Ubuntu/Raspbian Linux系统 需要5GB以上硬盘剩余空间 需要128MB以上内存( ...

  3. spring security开发步骤

    1.web.xml中加载spring ,spring security 2.spring security配置文件中配置好.... 3.自己写一个myFilter代替原有的FilterSecurity ...

  4. odoo生产物流

    odoo生产从raw materials location 自动消耗物料,产成品进入到finish productslocation. 而odoo自动产生的MO[manufacture Order], ...

  5. Linux Apache 给 awstats 创建 訪问password

    CentOS7 安装最新版本号 awstats ,在httpd.conf 中增加了alias,能够直接訪问网址就进入 浏览.十分不安全. 给訪问加上password的方法: [root@localho ...

  6. 3.nginx反向代理服务器+负载均衡

    nginx反向代理服务器+负载均衡 用nginx做反向代理和负载均衡非常简单, 支持两个用法: 1个proxy, 1个upstream,分别用来做反向代理,和负载均衡 以反向代理为例, nginx不自 ...

  7. python(40)- 进程、线程、协程及IO模型

    一.操作系统概念 操作系统位于底层硬件与应用软件之间的一层.工作方式:向下管理硬件,向上提供接口. 操作系统进行进程切换:1.出现IO操作:2.固定时间. 固定时间很短,人感受不到.每一个应用层运行起 ...

  8. 浅析nodejs的buffer类

    1.什么时候该用buffer,什么时候不该用 看一下如下的测试代码,分别是拼接各种不同长度的字符串,最后直接拼接了10MB的字符串 var string,string2,string3; var bu ...

  9. Java、C++、Python、Ruby、PHP、C#和JavaScript的理解

    Java.C++.Python.Ruby.PHP.C#和JavaScript和日本动漫里的那些大家熟悉的动漫人物结合起来.依据他们的身世.个人经历来生动的表达各编程语言的发展历程.原文内容例如以下:  ...

  10. C++再次理解虚表

    #include <iostream> using namespace std; class Base { public: virtual void fun1() { cout <& ...