uoj349 即时战略
题意:这是一道交互题。交互库中有一棵树。一开始只有1节点已知。需要在T次询问内使得n个节点都已知。一次询问explore(x,y),返回从x到y路径上第一个点,并将返回点标记为已知。
数据有区分。
标程:
#include<cstdio>
#include<time.h>
#include<algorithm>
#include "rts.h"
using namespace std;
const int N=;
int son[N][],fa[N],L[N],R[N],vis[N],E[],id[N],now,nxt,it;
int is_rt(int x) {return son[fa[x]][]!=x&&son[fa[x]][]!=x;}
int ran() {return (int)(rand()/RAND_MAX+0.5);}
void up(int x)
{
L[x]=R[x]=x;
if (son[x][]) L[x]=L[son[x][]];//leftest
if (son[x][]) R[x]=R[son[x][]];//rightest
}
void rot(int x)
{
int y=fa[x],z=fa[y],l=(son[y][]==x),r=l^;
if (!is_rt(y)) son[z][(son[z][]==y)]=x;
fa[x]=z;fa[y]=x;fa[son[x][r]]=y;
son[y][l]=son[x][r];son[x][r]=y;
up(y);up(x);
}
void spl(int x)
{
for (int y;!is_rt(x);rot(x))
if (!is_rt(y=fa[x]))
if (son[y][]==x^son[fa[y]][]==y) rot(x);else rot(y);
}
int find_rt(int x)
{
for (;!is_rt(x);x=fa[x]);
return x;
}
void accs(int x) {for (int t=;x;t=x,x=fa[x]) spl(x),son[x][]=t,up(x);}
void ins(int x)
{
now=find_rt();
while (!vis[x])
{
nxt=explore(now,x);
if (nxt==R[son[now][]]) now=son[now][];//father
else if (nxt==L[son[now][]]) now=son[now][];//son
else {//another splay
if (vis[nxt]) now=find_rt(nxt);//already have existed
else vis[nxt]=,fa[nxt]=now,now=nxt;//add a new point
}
}
accs(x);
}
void play(int n,int T,int dataType)
{
srand(time(NULL));
vis[]=;
for (int i=;i<=n;i++) id[i]=i;
random_shuffle(id+,id+n+);
if (dataType==)//chain
{
now=explore(,id[]);vis[now]=;
E[]=;E[]=now;
for (int i=;i<=n;i++)
if (!vis[id[i]])
{
it=ran();now=explore(E[it],id[i]);//注意explore的顺序(u->v)
if (!vis[now])//这一边
{
vis[E[it]=now]=;
while (E[it]!=id[i]) E[it]=explore(E[it],id[i]),vis[E[it]]=;//记得更改范围指针
}else {//另一边
it^=;
while (E[it]!=id[i]) E[it]=explore(E[it],id[i]),vis[E[it]]=;
}
}
return;
}
for (int i=;i<=n;i++) L[i]=R[i]=i;//初始化
for (int i=;i<=n;i++)
if (!vis[id[i]]) ins(id[i]);
}
易错点:1.注意lct之前的初始化L[i]=R[i]=i。并且不用每找到一个点就splay,新加入一个点access更新保证复杂度即可。
2.access不要写错,判定继续的条件应该是x而不是!is_rt(x)。
3.链的情况要更新边界。
技巧:可以用random_shuffle来避免一些数据的卡。
题解:lct/动态点分树
数据告诉我们:树T=nlogn,链T=n+logn.
树:
1.仿照CF772E的做法,可以通过点分来插入一个点。但不同的是,这不是一棵二叉树,在前向星上插入删除的复杂度太高,因此考虑动态点分树来支持动态加点。(然而我并不会写)
2.点分的思想也就是对树二分。因此我们树链剖分后在重链上二分也可以得到一样的效果。由于有加点,用lct即可。用splay维护每一条重链,因为splay的高度的log级别的,从根开始跳splay上的节点完成二分。讨论一下返回的已知点在询问点的儿子/父亲/另一个splay上->是否已知。最后access(x)更新树的形态。O(nlogn)。
链:
维护一段连续的已知点[L,R],对于一个未知点x,如果explore(L,x)是未知点,那么往R方向扩展,反之在L方向扩展。
每个点必定被explore一次O(n)。random第一次的询问是L还是R后,更改方向的次数期望是O(log n)或是说O(ln n)的。(证明:设E(n)表示扩展为长度为n的序列需要更改几次方向:E(n)=1+1/n*sigma(E[i])(i=[1,n-1])->E(n)-E(n-1)=1/n->E(n)=sigma(1/i)≈ln n)
所以总的是O(n+log n)。
uoj349 即时战略的更多相关文章
- 【Unity3D】使用鼠标键盘控制Camera视角(即时战略类游戏视角):缩近,拉远,旋转
今天写一个demo,要用到鼠标键盘控制三维视角,因此写了个脚本用于控制. 该脚本可以用于即时战略类游戏的视角,提供了缩进,拉伸,旋转.同时按住鼠标右键不放,移动鼠标可以实现第一人称视角的效果. usi ...
- D3D游戏编程系列(三):自己动手编写即时战略游戏之寻路
说起即时战略游戏,不得不提的一个问题是如何把一个物体从一个位置移动到另一个位置,当然,我说的不是瞬移,而是一个移动的过程,那么在这个移动的过程中我们如何来规划路线呢,这就不得不提到寻路了. 我所了解到 ...
- 【WC2018】即时战略
题目描述 小M在玩一个即时战略(Real Time Strategy)游戏.不同于大多数同类游戏,这个游戏的地图是树形的. 也就是说,地图可以用一个由 n个结点,n?1条边构成的连通图来表示.这些结点 ...
- [WC2018]即时战略——动态点分治(替罪羊式点分树)
题目链接: [WC2018]即时战略 题目大意:给一棵结构未知的树,初始时除1号点其他点都是黑色,1号点是白色,每次你可以询问一条起点为白色终点任意的路径,交互库会自动返回给你这条路径上与起点相邻的节 ...
- 【WC2018】即时战略(动态点分治,替罪羊树)
[WC2018]即时战略(动态点分治,替罪羊树) 题面 UOJ 题解 其实这题我也不知道应该怎么确定他到底用了啥.只是想法很类似就写上了QwQ. 首先链的部分都告诉你要特殊处理那就没有办法只能特殊处理 ...
- D3D游戏编程系列(四):自己动手编写即时战略游戏之网络同步
说到网络同步,这真是一个网络游戏的重中之重,一个好的网络同步机制,可以让玩家的用户体验感飙升,至少,我玩过的魔兽争霸在网络同步方面做得非常好,即便是网络状况很不稳定,依然可以保证用户数据不会出现意想不 ...
- 「WC2018即时战略」
「WC2018即时战略」 题目描述 小 M 在玩一个即时战略 (Real Time Strategy) 游戏.不同于大多数同类游戏,这个游戏的地图是树形的.也就是说,地图可以用一个由 \(n\) 个结 ...
- 【CSP-S膜你考】即时战略(模拟)
Problem B. 即时战略 (rts.c/cpp/pas) 注意 Input file: rts.in Output file: rts.out Time Limit : 2 seconds Me ...
- 「WC2018」即时战略
「WC2018」即时战略 考虑对于一条链:直接随便找点,然后不断问即可. 对于一个二叉树,树高logn,直接随便找点,然后不断问即可. 正解: 先随便找到一个点,问出到1的路径 然后找别的点,考虑问出 ...
随机推荐
- Linux命令(2):cat
cat命令是一个文本连接和查看的命令,用于文件的输出显示. 三大功能 一次显示整个文件. $ cat filename 从键盘创建一个文件.只能创建新文件,不能编辑已有文件. $ cat > f ...
- CometOJ Contest #3 C
题目链接:https://cometoj.com/contest/38/problem/C?problem_id=1542&myself=0&result=0&page=1&a ...
- 什么是PoE、PSE、PD设备?
一个完整的PoE系统包括供电端设备(PSE, Power Sourcing Equipment)和受电端设备(PD, Power Device)两部分.PSE设备是为以太网客户端设备供电的设备,同时也 ...
- Docker学习のDocker初识
一.Docker是什么 Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从Apache2.0协议开源. Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级.可移植的容器中,然 ...
- jdk1.8新特性学习
package com.xll.code.jdk1_8study; import com.xll.code.jdk1_8study.pojo.User; import org.junit.jupite ...
- 2019-10-9-dotnet-不申请额外数组空间合并多个只读数组列表
title author date CreateTime categories dotnet 不申请额外数组空间合并多个只读数组列表 lindexi 2019-10-09 15:15:10 +0800 ...
- 用于扩展目标跟踪的笛卡尔B-Spline车辆模型
(哥廷根大学) 摘要 文章提出了一种表示空间扩展物体轮廓的新方法,该方法适用于采用激光雷达跟踪未知尺寸和方向的车辆.我们在笛卡尔坐标系中使用二次均匀周期的B-Splines直接表示目标的星 - 凸形状 ...
- 调整VMware中虚拟机中Linux系统屏幕分辨率的问题
即:解决显示底部菜单栏以及安装软件中没有下一步的按钮用Tab键的问题 右击打开终端,输入以下命令: Xrandr Xrandr -s 1280x720 (自己选择一个分辨率即可) 原文:https: ...
- Java 基础 - 装箱, 拆箱
总结 1-装箱过程是通过调用包装器的valueOf方法实现的,而拆箱过程是通过调用包装器的 xxxValue方法实现的.(xxx代表对应的基本数据类型).例如:在装箱的时候自动调用的是Integer的 ...
- prometheus配置详情
https://prometheus.io/docs/prometheus/latest/configuration/configuration/ 下面监控宿主机和容器的内存,CPU,磁盘等状态 gr ...