【WC2018】即时战略(动态点分治,替罪羊树)
【WC2018】即时战略(动态点分治,替罪羊树)
题面
题解
其实这题我也不知道应该怎么确定他到底用了啥。只是想法很类似就写上了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】即时战略(动态点分治,替罪羊树)的更多相关文章
- [WC2018]即时战略——动态点分治(替罪羊式点分树)
题目链接: [WC2018]即时战略 题目大意:给一棵结构未知的树,初始时除1号点其他点都是黑色,1号点是白色,每次你可以询问一条起点为白色终点任意的路径,交互库会自动返回给你这条路径上与起点相邻的节 ...
- LOJ2341. 「WC2018」即时战略 [动态点分治]
LOJ 思路 考虑最蠢的暴力:枚举2~n,从1拉一条到他们的链,需要查询\(n^2\)次,显然不能通过. 考虑优化:如果拉的第一个点已经被访问过了,那么类似二分的做法,一次往那个方向多跳几步. 多跳几 ...
- luoguP3920 [WC2014]紫荆花之恋 动态点分治 + 替罪羊树
意外的好写..... 考虑点分 \(dis(i, j) \leq r_i + r_j\) 对于过分治中心一点\(u\),有 \(dis(i, u) - r_i = dis(j, u) + r_j\) ...
- bzoj3435 [Wc2014]紫荆花之恋(动态点分治+替罪羊树)
传送门(权限) 传送门(非权限) 题解 我终终终终终终于做出来啦!!! 作为一个没有学过替罪羊树的蒟蒻现场学了一下替罪羊树,作为一个平衡树都写数组版本的看着大佬的指针题解无语只能硬去理解然后照着抄了一 ...
- UOJ #55 & 洛谷 P3920 紫荆花之恋 —— 动态点分治+替罪羊树
题目:http://uoj.ac/problem/55 https://www.luogu.org/problemnew/show/P3920 参考博客:https://www.cnblogs.com ...
- 「WC2018即时战略」
「WC2018即时战略」 题目描述 小 M 在玩一个即时战略 (Real Time Strategy) 游戏.不同于大多数同类游戏,这个游戏的地图是树形的.也就是说,地图可以用一个由 \(n\) 个结 ...
- 【loj6145】「2017 山东三轮集训 Day7」Easy 动态点分治+线段树
题目描述 给你一棵 $n$ 个点的树,边有边权.$m$ 次询问,每次给出 $l$ .$r$ .$x$ ,求 $\text{Min}_{i=l}^r\text{dis}(i,x)$ . $n,m\le ...
- 【bzoj4372】烁烁的游戏 动态点分治+线段树
题目描述 给一颗n个节点的树,边权均为1,初始点权均为0,m次操作:Q x:询问x的点权.M x d w:将树上与节点x距离不超过d的节点的点权均加上w. 输入 第一行两个正整数:n,m接下来的n-1 ...
- 【bzoj3730】震波 动态点分治+线段树
题目描述 在一片土地上有N个城市,通过N-1条无向边互相连接,形成一棵树的结构,相邻两个城市的距离为1,其中第i个城市的价值为value[i].不幸的是,这片土地常常发生地震,并且随着时代的发展,城市 ...
- BZOJ3435[Wc2014]紫荆花之恋——动态点分治(替罪羊式点分树套替罪羊树)
题目描述 强强和萌萌是一对好朋友.有一天他们在外面闲逛,突然看到前方有一棵紫荆树.这已经是紫荆花飞舞的季节了,无数的花瓣以肉眼可见的速度从紫荆树上长了出来.仔细看看的话,这个大树实际上是一个带权树.每 ...
随机推荐
- python札记
进制转换 num = "0011"v = int(num, base=16)print(v)2->16
- python实现满二叉树递归循环
一.二叉树介绍点这片文章 二叉树及题目介绍 例题: 有一颗满二叉树,每个节点是一个开关,初始全是关闭的,小球从顶点落下, 小球每次经过开关就会把它的状态置反,这个开关为关时,小球左跑,为开时右跑.现在 ...
- Elasticsearch 5.0Head插件
Elasticsearch 5.0 —— Head插件部署指南 使用ES的基本都会使用过head,但是版本升级到5.0后,head插件就不好使了.下面就看看如何在5.0中启动Head插件吧! 官方 ...
- 快速为git添加一个用户
环境:用gitosis-admin管理git的权限. 前期git环境的搭建略去,主要给出快速添加一个用户的步骤: 在git bash中用“ssh-keygen -t rsa”生成公钥私钥,默认放到 “ ...
- [转帖]关于CPU Cache -- 程序猿需要知道的那些事
关于CPU Cache -- 程序猿需要知道的那些事 很早之前读过作者的blog 记得作者在facebook 工作.. 还写过mysql相关的内容 大拿 本文将介绍一些作为程序猿或者IT从业者应该知道 ...
- 剑指Offer(9)
题目: 给定一个double类型的浮点数base和int类型的整数exponent.求base的exponent次方. 解法: 要考虑到底数为0,指数为负数的情况,这道题主要考的是对边界值的思考. p ...
- java学习之—栈
/** * 栈 * Create by Administrator * 2018/6/11 0011 * 上午 10:20 **/ public class StackX { private int ...
- Golang的channel使用以及并发同步技巧
在学习<The Go Programming Language>第八章并发单元的时候还是遭遇了不少问题,和值得总结思考和记录的地方. 做一个类似于unix du命令的工具.但是阉割了一些功 ...
- C#通过Socket读取大量数据
在C#中经常会用到Socket去接收和发送数据,而且也是非常方便的,有时候我们会向服务端去请求数据,如果返回的数据量很大,比如超过10M甚至是更多,那么该怎样去接收数据呢?下面以一个在项目中用到的实例 ...
- 在页面中有overflow-y:auto属性的div,当出现滚动条,点击返回顶部按钮,内容回这个div最顶部
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...