题意:这是一道交互题。交互库中有一棵树。一开始只有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 即时战略的更多相关文章

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

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

  2. D3D游戏编程系列(三):自己动手编写即时战略游戏之寻路

    说起即时战略游戏,不得不提的一个问题是如何把一个物体从一个位置移动到另一个位置,当然,我说的不是瞬移,而是一个移动的过程,那么在这个移动的过程中我们如何来规划路线呢,这就不得不提到寻路了. 我所了解到 ...

  3. 【WC2018】即时战略

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

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

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

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

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

  6. D3D游戏编程系列(四):自己动手编写即时战略游戏之网络同步

    说到网络同步,这真是一个网络游戏的重中之重,一个好的网络同步机制,可以让玩家的用户体验感飙升,至少,我玩过的魔兽争霸在网络同步方面做得非常好,即便是网络状况很不稳定,依然可以保证用户数据不会出现意想不 ...

  7. 「WC2018即时战略」

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

  8. 【CSP-S膜你考】即时战略(模拟)

    Problem B. 即时战略 (rts.c/cpp/pas) 注意 Input file: rts.in Output file: rts.out Time Limit : 2 seconds Me ...

  9. 「WC2018」即时战略

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

随机推荐

  1. Lombok 常用注解

    Lombok Lombok 能以简单的注解形式来简化 java 代码,提高开发人员的开发效率.例如开发中经常需要写的 javaBean,都需要花时间去添加相应的 getter/setter,也许还要去 ...

  2. kettle 中 java.lang.ClassCastException: [B cannot be cast to java.lang.String报错的解决方法

    问题描述:从数据库中查询出的某字段是json类型数据,然后在json输入步骤报错java.lang.ClassCastException: [B cannot be cast to java.lang ...

  3. <爬虫实战>糗事百科

    1.糗事百科段子.py # 目标:爬取糗事百科段子信息(文字) # 信息包括:作者头像,作者名字,作者等级,段子内容,好笑数目,评论数目 # 解析用学过的几种方法都实验一下①正则表达式.②Beauti ...

  4. 1-MySQL高级-视图

    视图 1. 问题 对于复杂的查询,往往是有多个数据表进行关联查询而得到,如果数据库因为需求等原因发生了改变,为了保证查询出来的数据与之前相同,则需要在多个地方进行修改,维护起来非常麻烦 解决办法:定义 ...

  5. vue axios简单配置

    参考:https://www.cnblogs.com/sophie_wang/p/7844119.html 1. 安装 npm install axios 2. main.js import axio ...

  6. 人脸识别--Open set和Close set的区别

    训练和测试人脸识别分类器时,总会提到Open-set和Close-set.这俩词到底是什么概念呢?有什么区别呢? 所谓close-set,就是所有的测试集都在训练集中出现过.所以每次的预测直接得出测试 ...

  7. RabbitMQ学习第一记:用java连接RabbitMQ

    1.什么是RabbitMQ MQ(Message Queue):消息队列,是服务端设计的一个可以存储大量消息的队列,并提供客户端操作队列的方法:生产队列(向队列中添加数据).消费队列(从队列中取数据) ...

  8. anaconda新建环境

    安装tensorflow等如下: https://blog.csdn.net/Gransand/article/details/80713810 修改默认打开目录如下: https://blog.cs ...

  9. c_ 数据结构_图_邻接矩阵

    程序主要实现了图的深度遍历和广度遍历. #include <stdio.h> #include <stdlib.h> #include <string.h> #de ...

  10. CSIC_716_20191113【装饰器进阶以及迭代器】

    装饰器的进阶主要包含叠加装饰器和有参装饰器 叠加装饰器:在一个被装饰的对象中,添加多个装饰器. 为什么要用叠加装饰器的原因:    -每一个新的功能都应该写一个新的装饰器,否则会导致,代码冗余,结构不 ...