洛谷 P2056 [ZJOI2007]捉迷藏(动态点分治)

本文介绍了洛谷P2056题目的解题思路,通过动态点分治的方法解决捉迷藏问题。文章提到了在每个节点建立双堆,分别记录子树内点到节点的距离和子树中最大距离信息,以及如何更新全局答案。最终,算法的时间复杂度为O(nlog^2n)。
摘要由CSDN通过智能技术生成

题目链接

冒着滥用此题将封号的风险测了七发RP才过……

每个点建两个双堆,堆a表示这个点所在的子树里所有点到他点分树中父亲的距离,堆b表示所有点分树子树中到他距离最大的个点的距离,堆c用来存全局答案,显然全局答案就是每个堆b中最大值和次大值的和

点分树上暴跳父亲复杂度是log的,所以总复杂度是 n l o g 2 n nlog^2n nlog2n

代码如下:

#include<bits/stdc++.h>
using namespace std;

inline int read()
{
   
    int X=0,w=0; char ch=0;
    while(!isdigit(ch)) {
   w|=ch=='-';ch=getchar();}
    while(isdigit(ch)) X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
    return w?-X:X;
}

struct heap
{
   
    priority_queue<int> q1,q2;

    void insert(int val)
    {
   
        q1.push(val);
    }

    void erase(int val)
    {
   
        q2.push(val);
    }

    int top()
    {
   
        while(q2.size()&&q1.top()==q2.top()) q1.pop(),q2.pop();
        return q1.top();
    }

    void pop()
    {
   
        while(q2.size()&&q1.top()==q2.top()) q1.pop(),q2.pop();
        if(q1.size()) q1.pop();
    }

    int top2()
    {
   
        int val=top();pop();
        int res=top();insert(val);
        return res;
    }

    int size()
    {
   
        return q1.size()-q2.size();
    }
}a[100010],b[100010],c;

int sz[100010],deep[100010];
int fa[100010],f
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值