【WC2018】即时战略(动态点分治,替罪羊树)

题面

UOJ

题解

其实这题我也不知道应该怎么确定他到底用了啥。只是想法很类似就写上了QwQ。

首先链的部分都告诉你要特殊处理那就没有办法只能特殊处理了QWQ。

首先听说有一种均摊\(log\)的\(LCT\)做法。

即每次随便\(explore\)一个点,如果这个点未被访问过,直接加入然后继续。

否则在\(LCT\)重链组成的\(Splay\)上跳。

这样子均摊复杂度是\(O(nlogn)\),均摊的询问次数也是\(O(nlogn)\)。

然而似乎会被卡。

另一种做法是动态维护点分树。

假装我们有一个点分树,这样子每次询问的时候,如果确定了一个已知节点,那么我们从当前节点向着那个节点的点分树方向移动,这样子可以证明移动次数不会超过一个\(log\)。

然而新加入若干点之后点分治的树可能不在平衡,导致复杂度不正确了。

那么类似替罪羊树的思想,如果点分树之间的大小不满足平衡,则拆掉重建。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<map>
#include "rts.h"
using namespace std;
#define MAX 300300
const double alpha=0.75;
int n,p[MAX],tot;
bool vis[MAX];
namespace Chain
{
void Solve()
{
int L=1,R=1;
for(int i=1;i<=tot;++i)
{
if(vis[p[i]])continue;
int u=p[i],x=explore(L,u);
if(vis[x])x=R,R=u;
else L=u,vis[x]=true;
while(u!=x)vis[x=explore(x,u)]=true;
}
}
}
struct Line{int v,next;}e[MAX<<1];
int h[MAX],cnt=1;
inline void Add(int u,int v){e[cnt]=(Line){v,h[u]};h[u]=cnt++;}
int Fa[MAX],size[MAX];
bool del[MAX];
int book[MAX],tim;
void Clear(int u,int ff)
{
del[u]=false;
for(int i=h[u];i;i=e[i].next)
if(e[i].v!=ff&&book[e[i].v]!=tim)
Clear(e[i].v,u);
}
int Size,mx,rt,root;
void Getroot(int u,int ff)
{
int ret=0;size[u]=1;
for(int i=h[u];i;i=e[i].next)
{
int v=e[i].v;if(v==ff||book[v]==tim)continue;
Getroot(v,u);size[u]+=size[v];ret=max(ret,size[v]);
}
ret=max(ret,Size-size[u]);
if(ret<mx)mx=ret,rt=u;
}
void Divide(int u)
{
book[u]=tim;
for(int i=h[u];i;i=e[i].next)
{
int v=e[i].v;if(book[v]==tim)continue;
Size=mx=size[v];Getroot(v,u);
Fa[rt]=u;size[rt]=size[v];Divide(rt);
}
}
void ReBuild(int u)
{
++tim;for(int i=Fa[u];i;i=Fa[i])book[i]=tim;
Clear(u,0);Size=mx=size[u];Getroot(u,0);
if(u==root)root=rt;
Fa[rt]=Fa[u];size[rt]=size[u];Divide(rt);
}
void Update(int u)
{
if(!Fa[u]){if(del[u])ReBuild(u);return;}
++size[Fa[u]];if(Fa[u]&&alpha*size[Fa[u]]<size[u])del[Fa[u]]=true;
Update(Fa[u]);if(del[u])ReBuild(u);
}
void Find(int x)
{
int u=root;
while(!vis[x])
{
int v=explore(u,x);
if(vis[v]){while(u!=Fa[v])v=Fa[v];u=v;}
else Add(u,v),Add(v,u),Fa[v]=u,size[v]=1,Update(v),vis[v]=true,u=v;
} }
void play(int _n,int T,int dataType)
{
n=_n;vis[1]=true;root=1;size[1]=1;
for(int i=2;i<=n;++i)p[++tot]=i;
random_shuffle(&p[1],&p[tot+1]);
if(dataType==3){Chain::Solve();return;}
for(int i=1;i<=tot;++i)if(!vis[p[i]])Find(p[i]);
}

【WC2018】即时战略(动态点分治,替罪羊树)的更多相关文章

  1. [WC2018]即时战略——动态点分治(替罪羊式点分树)

    题目链接: [WC2018]即时战略 题目大意:给一棵结构未知的树,初始时除1号点其他点都是黑色,1号点是白色,每次你可以询问一条起点为白色终点任意的路径,交互库会自动返回给你这条路径上与起点相邻的节 ...

  2. LOJ2341. 「WC2018」即时战略 [动态点分治]

    LOJ 思路 考虑最蠢的暴力:枚举2~n,从1拉一条到他们的链,需要查询\(n^2\)次,显然不能通过. 考虑优化:如果拉的第一个点已经被访问过了,那么类似二分的做法,一次往那个方向多跳几步. 多跳几 ...

  3. luoguP3920 [WC2014]紫荆花之恋 动态点分治 + 替罪羊树

    意外的好写..... 考虑点分 \(dis(i, j) \leq r_i + r_j\) 对于过分治中心一点\(u\),有 \(dis(i, u) - r_i = dis(j, u) + r_j\) ...

  4. bzoj3435 [Wc2014]紫荆花之恋(动态点分治+替罪羊树)

    传送门(权限) 传送门(非权限) 题解 我终终终终终终于做出来啦!!! 作为一个没有学过替罪羊树的蒟蒻现场学了一下替罪羊树,作为一个平衡树都写数组版本的看着大佬的指针题解无语只能硬去理解然后照着抄了一 ...

  5. UOJ #55 & 洛谷 P3920 紫荆花之恋 —— 动态点分治+替罪羊树

    题目:http://uoj.ac/problem/55 https://www.luogu.org/problemnew/show/P3920 参考博客:https://www.cnblogs.com ...

  6. 「WC2018即时战略」

    「WC2018即时战略」 题目描述 小 M 在玩一个即时战略 (Real Time Strategy) 游戏.不同于大多数同类游戏,这个游戏的地图是树形的.也就是说,地图可以用一个由 \(n\) 个结 ...

  7. 【loj6145】「2017 山东三轮集训 Day7」Easy 动态点分治+线段树

    题目描述 给你一棵 $n$ 个点的树,边有边权.$m$ 次询问,每次给出 $l$ .$r$ .$x$ ,求 $\text{Min}_{i=l}^r\text{dis}(i,x)$ . $n,m\le ...

  8. 【bzoj4372】烁烁的游戏 动态点分治+线段树

    题目描述 给一颗n个节点的树,边权均为1,初始点权均为0,m次操作:Q x:询问x的点权.M x d w:将树上与节点x距离不超过d的节点的点权均加上w. 输入 第一行两个正整数:n,m接下来的n-1 ...

  9. 【bzoj3730】震波 动态点分治+线段树

    题目描述 在一片土地上有N个城市,通过N-1条无向边互相连接,形成一棵树的结构,相邻两个城市的距离为1,其中第i个城市的价值为value[i].不幸的是,这片土地常常发生地震,并且随着时代的发展,城市 ...

  10. BZOJ3435[Wc2014]紫荆花之恋——动态点分治(替罪羊式点分树套替罪羊树)

    题目描述 强强和萌萌是一对好朋友.有一天他们在外面闲逛,突然看到前方有一棵紫荆树.这已经是紫荆花飞舞的季节了,无数的花瓣以肉眼可见的速度从紫荆树上长了出来.仔细看看的话,这个大树实际上是一个带权树.每 ...

随机推荐

  1. PS 制作彩色烟雾

  2. c++局部变量在外可用的方法

    C++的局部变量在作用域结束后,一般都会被回收.如下面这段代码 map<a*, b*> _map; void fun() { a _a; b _b; _map[&_a] = &am ...

  3. Svn基本操作

    日常开发中使用到的Svn基本操作 svn      https://tortoisesvn.net/ https://www.visualsvn.com/server/download/   1. 检 ...

  4. ESLint常见命令(规则表)

    1 禁用 ESLint: /* eslint-disable */ ; console.log(a); /* eslint-enable */ 2 禁用一条规则: /*eslint-disable n ...

  5. spring IOC源码分析(ApplicationContext)

    在上一篇文章中,我们以BeanFactory这条主线进行IOC的源码解析的,这里,将以ApplicationContext这条线进行分析.先看使用方法: @Test public void testA ...

  6. 18个Python高效编程技巧,Mark!

    初识Python语言,觉得python满足了我上学时候对编程语言的所有要求.python语言的高效编程技巧让我们这些大学曾经苦逼学了四年c或者c++的人,兴奋的不行不行的,终于解脱了.高级语言,如果做 ...

  7. python数据结构与算法第五天【顺序表】

    1.列表存储的两种方式 (1)元素内置方式 采用元素内置的方式只能存放同类型元素的数据类型,例如列表中的元素都为整形,元素类型相同,每个元素存放的地址空间大小也相同,则列表中每个元素都是顺序存放的 ( ...

  8. 微信小程序wxml無法實現頁面跳轉的問題

    wxml的 navigator的url設置后無法跳轉? 檢查要跳轉的頁面是否是在APP.json的tabBar里註冊過,如果是tabBar頁面是不能用wx.navigateTo和wx.Redirect ...

  9. vue之v-for使用说明

    demo.html <!DOCTYPE html> <html lang="en" xmlns:v-bind="http://www.w3.org/19 ...

  10. cuda编程-矩阵乘法(1)

    本方法采用简单的单线程计算每组行和列乘加运算 代码如下: #include <stdio.h> #include <stdlib.h> #include <iostrea ...