【UOJ#349】[WC2018] 即时战略
题意
一开始已知一号点。
每次可以选定一个已知点和一个未知点,然后交互库会返回从已知点出发到达未知点路径上的第二个点。
要求在有限步之内知道每一个点。
次数要求:
链的情况要求 \(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] 即时战略的更多相关文章
- [WC2018]即时战略——动态点分治(替罪羊式点分树)
题目链接: [WC2018]即时战略 题目大意:给一棵结构未知的树,初始时除1号点其他点都是黑色,1号点是白色,每次你可以询问一条起点为白色终点任意的路径,交互库会自动返回给你这条路径上与起点相邻的节 ...
- 「WC2018即时战略」
「WC2018即时战略」 题目描述 小 M 在玩一个即时战略 (Real Time Strategy) 游戏.不同于大多数同类游戏,这个游戏的地图是树形的.也就是说,地图可以用一个由 \(n\) 个结 ...
- [WC2018]即时战略(LCT,splay上二分)
[UOJ题面]http://uoj.ac/problem/349 一道非常好的与数据结构有关的交互题. 首先先看部分分做法, 一上来我们肯定得钦定一个 \(explore\) 的顺序,直接随机就好. ...
- WC2018 即时战略
交互题 一棵树,一开始只有 1 号点是已知的,其他的都是未知的,你可以调用函数 explore(x,y) ,其中 x 必须是已知的,函数会找到 x 到 y 路径上第二个点,并把它标成已知,求最小步数使 ...
- 【WC2018】即时战略(动态点分治,替罪羊树)
[WC2018]即时战略(动态点分治,替罪羊树) 题面 UOJ 题解 其实这题我也不知道应该怎么确定他到底用了啥.只是想法很类似就写上了QwQ. 首先链的部分都告诉你要特殊处理那就没有办法只能特殊处理 ...
- 【WC2018】即时战略
题目描述 小M在玩一个即时战略(Real Time Strategy)游戏.不同于大多数同类游戏,这个游戏的地图是树形的. 也就是说,地图可以用一个由 n个结点,n?1条边构成的连通图来表示.这些结点 ...
- 「WC2018」即时战略
「WC2018」即时战略 考虑对于一条链:直接随便找点,然后不断问即可. 对于一个二叉树,树高logn,直接随便找点,然后不断问即可. 正解: 先随便找到一个点,问出到1的路径 然后找别的点,考虑问出 ...
- loj2341「WC2018」即时战略(随机化,LCT/动态点分治)
loj2341「WC2018」即时战略(随机化,LCT/动态点分治) loj Luogu 题解时间 对于 $ datatype = 3 $ 的数据,explore操作次数只有 $ n+log n $ ...
- 【Unity3D】使用鼠标键盘控制Camera视角(即时战略类游戏视角):缩近,拉远,旋转
今天写一个demo,要用到鼠标键盘控制三维视角,因此写了个脚本用于控制. 该脚本可以用于即时战略类游戏的视角,提供了缩进,拉伸,旋转.同时按住鼠标右键不放,移动鼠标可以实现第一人称视角的效果. usi ...
随机推荐
- Vue知识整理15:组件注册
采用局部注册组件: 将代码放在vue的一个实例中,而不是单列申明.
- 网易云课堂_C++程序设计入门(下)_第7单元:出入虽同趣,所向各有宜 – 文件输入和输出_第7单元 - 作业2:编程互评
第7单元 - 作业2:编程互评 查看帮助 返回 提交作业(剩余10天) 完成并提交作业 作业批改 互评训练 互评作业 自评作业 成绩公布 查看成绩 由于在线编程不支持 ...
- 2019暑假第三周(HDFS和HBase)
Hadoop的核心是HDFS和MapReduce. 1.分布式文件系统HDFS理论方面的认知学习. 2.HDFS编程实践. 3.分布式数据库HBase.
- codeforces 1186C Vus the Cossack and Strings
题目链接:https://codeforc.es/contest/1186/problem/C 题目大意:xxxxx(自认为讲不清.for instance) 例如:a="01100010& ...
- 关于BeautifulSoup4 解析器的说明
一.解析器概述 如同前几章笔记,当我们输入: soup=BeautifulSoup(response.body) 对网页进行析取时,并未规定解析器,此时使用的是python内部默认的解析器“html. ...
- 加载动态链接库——dlopen dlsym dlclose
DLOPEN DLMOPEN DLCLOSE NAME dlclose, dlopen, dlmopen - 打开/关闭共享对象 SYNOPSIS #include <dlfcn.h&g ...
- 循环结构 :for
循环结构 :for 循环四要素: 1.初始化条件 2.循环条件 3.循环体 4.迭代条件 格式: for(初始化条件;循环条件;迭代条件){ 循环体; } 执行顺序 :1 -> 2 -> ...
- C++自学教程第一课——你好世界,我是柠檬鲸。
C++系列教程现在在自己学校的一个博客平台发布,几个朋友一起搭建的 [C++基础教程系列](https://blog.ytmaxoj.org/cpp_basic_liuary-0/) 下面是原来的正文 ...
- electron实现qq快捷登录!
之前本来想不写这个功能的,结果客户死活要qq登录! 实在没办法就写了,顺便写个文章!在写之前有两个问题:1: 打开qq授权页面点击页面中的链接会又打开一个页面! .....2: 授权之后是否成功很难去 ...
- 使用 VS Code 搭建 TypeScript 开发环境
使用 VS Code 搭建 TypeScript 开发环境 TypeScript 是 JavaScript 的超集,TypeScript 只是增强了 JavaScript 而非改变了 JavaScri ...