题目链接

题意

一开始已知一号点。

每次可以选定一个已知点和一个未知点,然后交互库会返回从已知点出发到达未知点路径上的第二个点。

要求在有限步之内知道每一个点。

次数要求:

链的情况要求 \(O(n)\)

其余是 \(O(nlogn)\)

Sol

首先是链的情况,记录当前左右端点不断往后探索即可。

然后是树,初始想法肯定就是不断迭代,最坏情况是 \(O(n^2)\) 的。

我们的瓶颈在于如果树的深度比较大,我们迭代的时候来回走了很多个圈就不好处理。

那么我们很容易想到用点分树来优化我们迭代的过程。

于是动态维护点分树即可。

每次新加一个点的时候直接加入,向上更新点分树祖先的 \(size\) ,设定一个平衡因子,当当前子树大小过大时就把当前子树暴力重构一下。记录每一个点在点分树中的深度就很好做了。

code:

#include<bits/stdc++.h>
#include "rts.h"
using namespace std;
const int N=3e5+10;
namespace TP3{
int n;int lnow,rnow;bool del[N];int S[N];
void work(int _n){
n=_n;
lnow=rnow=1;for(int i=1;i<n;++i) S[i]=i+1;del[1]=1;
srand(time(NULL));random_shuffle(S+1,S+n);
for(int i=1;i<n;++i){
int now=lnow;bool f=0;
while(!del[S[i]]) {
int v=explore(now,S[i]);
if(del[v]) now=rnow,f=1;
else {
del[v]=1;now=v;
if(f==0) lnow=now;
else rnow=now;
}
}
if(rand()&1) swap(lnow,rnow);
}
return;
}
}
namespace Sol{
int n;
typedef double db;
const db alpha=0.7;
struct edge{int to,next;}a[N<<1];
int head[N],cnt=0;
inline void add(int x,int y){a[++cnt]=(edge){y,head[x]};head[x]=cnt;}
int fa[N],vis[N],size[N],f[N],que[N],had[N],mark[N],sz[N],dep[N];
int rt;int now,SZ,RT,UP;
void Find(int u,int fr){
sz[u]=1,f[u]=0;
for(int v,i=head[u];i;i=a[i].next){
v=a[i].to;if(v==fr||vis[v]) continue;
Find(v,u);sz[u]+=sz[v];
f[u]=max(f[u],sz[v]);
}
f[u]=max(f[u],SZ-sz[u]);
if(!RT||(f[u]<f[RT])) RT=u;
}
void Build(int u,int fr){
fa[u]=fr;size[u]=1;dep[u]=dep[fr]+1;vis[u]=1;
for(int v,i=head[u];i;i=a[i].next){
v=a[i].to;if(dep[v]<UP||vis[v]) continue;
RT=0;SZ=sz[v];Find(v,u);
int To=RT;Build(To,u);
size[u]+=size[To];
}
return;
}
void Clear(int u,int fa){
vis[u]=0,mark[u]=0;
for(int v,i=head[u];i;i=a[i].next){v=a[i].to;if(v==fa||dep[v]<UP) continue;Clear(v,u);}
return;
}
inline void Rebuild(int u){// 重构子树
SZ=size[u];UP=dep[u];RT=0;
Clear(u,0);Find(u,0);if(rt==u) rt=RT;
Build(RT,fa[u]);
return;
}
void Maintain(int u){// 向上更新点分树 size 并判断重构
if(!fa[u]) {if(mark[u]) Rebuild(u);return;}
++size[fa[u]];
if(size[fa[u]]*alpha<size[u]) mark[fa[u]]=1;
Maintain(fa[u]);
if(mark[u]) Rebuild(u);// 找到最上面需要重构的点
return;
}
void work(int _n){
n=_n;
for(int i=1;i<n;++i) que[i]=i+1;
srand(time(NULL));
random_shuffle(que+1,que+n);
had[1]=size[1]=vis[1]=rt=1,dep[1]=1;
int tot=1;
for(int i=1;i<n;++i) {
now=rt;
while(!had[que[i]]){
int p=explore(now,que[i]);
if(had[p]) {
while(now!=fa[p]) p=fa[p];now=p;
}
else {
++tot;had[p]=1;
add(now,p),add(p,now);
fa[p]=now,size[p]=1,vis[p]=1,dep[p]=dep[now]+1;
Maintain(p);now=p;
}
}
}
}
}
void play(int n, int T, int dataType) {
if(dataType==3) TP3::work(n);
else Sol::work(n);
}

【UOJ#349】[WC2018] 即时战略的更多相关文章

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

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

  2. 「WC2018即时战略」

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

  3. [WC2018]即时战略(LCT,splay上二分)

    [UOJ题面]http://uoj.ac/problem/349 一道非常好的与数据结构有关的交互题. 首先先看部分分做法, 一上来我们肯定得钦定一个 \(explore\) 的顺序,直接随机就好. ...

  4. WC2018 即时战略

    交互题 一棵树,一开始只有 1 号点是已知的,其他的都是未知的,你可以调用函数 explore(x,y) ,其中 x 必须是已知的,函数会找到 x 到 y 路径上第二个点,并把它标成已知,求最小步数使 ...

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

    [WC2018]即时战略(动态点分治,替罪羊树) 题面 UOJ 题解 其实这题我也不知道应该怎么确定他到底用了啥.只是想法很类似就写上了QwQ. 首先链的部分都告诉你要特殊处理那就没有办法只能特殊处理 ...

  6. 【WC2018】即时战略

    题目描述 小M在玩一个即时战略(Real Time Strategy)游戏.不同于大多数同类游戏,这个游戏的地图是树形的. 也就是说,地图可以用一个由 n个结点,n?1条边构成的连通图来表示.这些结点 ...

  7. 「WC2018」即时战略

    「WC2018」即时战略 考虑对于一条链:直接随便找点,然后不断问即可. 对于一个二叉树,树高logn,直接随便找点,然后不断问即可. 正解: 先随便找到一个点,问出到1的路径 然后找别的点,考虑问出 ...

  8. loj2341「WC2018」即时战略(随机化,LCT/动态点分治)

    loj2341「WC2018」即时战略(随机化,LCT/动态点分治) loj Luogu 题解时间 对于 $ datatype = 3 $ 的数据,explore操作次数只有 $ n+log n $ ...

  9. 【Unity3D】使用鼠标键盘控制Camera视角(即时战略类游戏视角):缩近,拉远,旋转

    今天写一个demo,要用到鼠标键盘控制三维视角,因此写了个脚本用于控制. 该脚本可以用于即时战略类游戏的视角,提供了缩进,拉伸,旋转.同时按住鼠标右键不放,移动鼠标可以实现第一人称视角的效果. usi ...

随机推荐

  1. python3 导入模块

    python3导入模块和python2  有些不同   需要指定相对目录 如,在Project下有一个nlp目录里面有一个ltp模块,则 from n1.ltp import Clawer

  2. jest 的 coverage 提示 unknown 的解决方案

    概述 这几天玩 jest ,我在运行单元测试之后 coverage 总是显示 unknown,花了很多时间排查原因,最后终于想明白了,记录下来,供以后开发时参考,相信对其他人也有用. coverage ...

  3. Openstack_通用模块_Oslo_vmware 创建 vSS PortGroup

    目录 目录 vSS vSSPG vSphere SDK 中相关的网络对象 创建 vSS PortGroup vSS & vSSPG vSS(Standard vSwitch 标准交换机) 为在 ...

  4. 一种局部二值化算法:Sauvola算法

    之前接触过全局二值化(OTSU算法),还有OPENCV提供的自适应二值化,最近又了解到一种新的局部二值化算法,Sauvola算法. 转载自:http://www.dididongdong.com/ar ...

  5. Jmeter 后置处理器--jp@gc - JSON/YAML Path Extractor & JSON Extractor

    后置处理器--jp@gc - JSON/YAML Path Extractor 1.需要下载插件,地址: 解压后把对应jar包放置对应的lib和lib/ext目录下,重启Jmeter: 2.在需要提取 ...

  6. 【MM系列】SAP 各种冲销凭证

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[MM系列]SAP 各种冲销凭证   前言部分 ...

  7. Environment Modules简单使用

    Environment Modules简单使用 Environment Modules简介 Typically users initialize their environment when they ...

  8. Flask框架(一)—— Flask简介

    Flask框架(一)—— Flask简介 目录 Flask框架介绍 一.Flask简介 二.flask安装与使用 1.安装 2.使用 3.简单案例——flask实现用户登录 Flask框架介绍 一.F ...

  9. fastjson @JSONField

    此文来源于:https://blog.51cto.com/xiaok007/2164029 1.作用在FIELD(成员变量上) 注意:1.若属性是私有的,必须有set*方法.否则无法反序列化. pac ...

  10. IDEA 快捷键 (长期更新)

    自动清除无效 import 和 清除无效 import  ctrl+alt+o