[题目链接]

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. 为了安全,linux下如何使用某个用户启动某个进程?

    安全里有个原则,叫最小权限原则 根据这个原则,对于启动某个应用或者进程,应该赋予其最小权限,根据应用权限要求,创建一个相应权限的用户,赋予其应用相应的权限,然后使用这个用户启用这个应用 如何使用某个用 ...

  2. How to create a freehand tool

    http://forums.esri.com/Thread.asp?c=159&f=1707&t=283694&mc=1 http://blog.sina.com.cn/s/b ...

  3. HDOJ1160 Fat Mouse&#39;s Speed

    FatMouse's Speed pid=1160">http://acm.hdu.edu.cn/showproblem.php?pid=1160 最长递增子序列问题的一个变体.实际上 ...

  4. vim 自动补全

    1. vim编辑器自带关键字补全 触发: ctrl + n  or ctrl + p 补全命令: <C-n>              普通关键字 [能够根据buffer以及标签文件列表等 ...

  5. 安卓UI适配限定符

    引言 对于程序在不同尺寸的Android机器上执行,对UI的适用性造成了额外的开销,只是限定符的出现,非常方便的攻克了这个问题.通过创建限定符相关的文件夹来解决资源的载入. 限定符用处 限定符(mdp ...

  6. python-pyDes-ECB加密-DES-DES3加密

    网上的教程都他妹的是抄的,抄也就算了,还改抄错了,害我写了一两天都没找到原因,直接去官网看,找例子很方便 官网链接:http://twhiteman.netfirms.com/des.html 一个小 ...

  7. 按照HashMap中value值进行排序

    import java.io.BufferedReader; import java.io.FileInputStream; import java.io.FileNotFoundException; ...

  8. 自动提交form表单

    <form class="form-inline" name='MD5form' method="post" action="<?php ...

  9. 不为客户连接创建子进程的并发回射服务器( poll实现 )

    前言 在上文中,我使用select函数实现了不为客户连接创建子进程的并发回射服务器( 点此进入 ).但其中有个细节确实有点麻烦,那就是还得设置一个client数组用来标记select监听描述符集中被设 ...

  10. VB.NET版机房收费系统—数据库设计

    之前第一遍机房收费的时候,用的数据库是别人的.认知也仅仅能建立在别人的基础上,等自考中<数据库系统原理>这本书学完了之后,再去看曾经的数据库,发现数据库真的还须要进一步的优化.以下是我设计 ...