[UOJ题面]http://uoj.ac/problem/349

一道非常好的与数据结构有关的交互题。

首先先看部分分做法,

一上来我们肯定得钦定一个 \(explore\) 的顺序,直接随机就好。

当 \(n\) 很小的时候就是直接从 1 号点一路 \(explore\) 过去就好了,这样次数是 \(O(n^2)\) 的。

由于完全二叉树树高是 log 的,所以它实际也能过第二个包。

然后来看一下链的情况,稍加思考我们可以得到这么一个做法:就是维护当前已经 \(explore\) 的点的连续区间的左右端点,这样就只需往两边扩展了

这部分是 \(O(n)\) 的。能通过第三个包。

我们把这个想法移到树上,于是就拿一个LCT来维护已经 \(explore\) 出来的点。

那么我们的问题就是怎么快速找到一个新点他在哪,然后我们写一个 \(Splay\) 上二分。

因为询问得到的是 \(now\) 的邻点,而当前这颗 \(Splay\) 上 \(now\) 的邻点只有前驱和后继,那么只要分三种情况讨论一下下一步去哪里就行:

(1)前驱(2)后继(3)它属于另一个 \(Splay\),直接去它那个根就行。

至于找前驱跟后继的话,可以拿 \(Splay\) 顺便维护出来。(可以参考Code)

一些细节:

为了保证复杂度,每次寻点结束时记得 \(Access\);

找根的时候不能 \(Splay\) 否则过不去 \(\text{Extra Test}\)。

最后把算法三、四合起来就行。

#include "rts.h"
#include "algorithm"
using namespace std; const int N=300005;
int vis[N];
int p[N]; #define lc(x) (ch[x][0])
#define rc(x) (ch[x][1]) int ch[N][2],f[N],L[N],R[N]; int g(int x)
{
return rc(f[x])==x;
} int nrt(int x)
{
return lc(f[x])==x || rc(f[x])==x;
} void up(int x)
{
L[x]=R[x]=x;
if(lc(x)) L[x]=L[lc(x)];
if(rc(x)) R[x]=R[rc(x)];
} void rot(int x)
{
int y=f[x],i=g(x);
if(nrt(y))
ch[f[y]][g(y)]=x;
f[x]=f[y];
ch[y][i]=ch[x][i^1];
f[ch[x][i^1]]=y;
ch[x][i^1]=y;
f[y]=x;
up(y);
} void splay(int x)
{
for(int y=f[x];nrt(x);rot(x),y=f[x])
if(nrt(y))
rot(g(x)==g(y)?y:x);
up(x);
} void access(int x)
{
for(int y=0;x;y=x,x=f[x])
{
splay(x);
rc(x)=y;
}
} int gr(int x)
{
for(;nrt(x);x=f[x]); return x;
} void play(int n, int T, int dataType) {
vis[1]=1;
if(dataType==2)
{
for(int i=2; i<=n; i++)
{
if(vis[i])
continue;
int now=1;
while(now!=i) {
now=explore(now,i);
vis[now]=1;
}
}
}
else if(dataType==3)
{
for(int i=1;i<=n;i++)p[i]=i;
int l,r;
l=r=1;
srand(20030118);
for(int i=1;i<=5*n;i++)
{
int x=rand()%n+1;
int y=rand()%n+1;
swap(p[x],p[y]);
}
for(int i,j=1;j<=n;j++)
{
i=p[j];
if(vis[i])
continue;
int now=explore(l,i);
if(!vis[now])
{
vis[now]=1;
while(now!=i) {
now=explore(now,i);
vis[now]=1;
}
l=i;
}
else
{
now=explore(r,i);
vis[now]=1;
while(now!=i) {
now=explore(now,i);
vis[now]=1;
}
r=i;
}
}
}
else
{
for(int i=1;i<=n;i++)p[i]=i;
srand(20030118);
for(int i=1;i<=5*n;i++)
{
int x=rand()%n+1;
int y=rand()%n+1;
swap(p[x],p[y]);
}
for(int i,j=1;j<=n;j++)
{
i=p[j];
if(vis[i])
continue;
int now=gr(1);
while(now!=i)
{
while(1)
{
int t=explore(now,i);
if(t==R[lc(now)]) now=lc(now);
else if(t==L[rc(now)]) now=rc(now);
else {
if(!vis[t])
vis[t]=1,f[t]=now;
now=gr(t);
break;
}
}
}
access(now);
}
}
}

[WC2018]即时战略(LCT,splay上二分)的更多相关文章

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

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

  2. 「WC2018即时战略」

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

  3. 【UOJ349】【WC2018】即时战略 LCT 动态点分治

    这是一道交互题 题目大意 有一棵\(n\)个点的树.最开始\(1\)号点是白的,其他点是黑的. 每次你可以执行一个操作:\(explore(x,y)\).要求\(x\)是一个白点.该函数会返回从\(x ...

  4. WC2018 即时战略

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

  5. 【UOJ#349】[WC2018] 即时战略

    题目链接 题意 一开始已知一号点. 每次可以选定一个已知点和一个未知点,然后交互库会返回从已知点出发到达未知点路径上的第二个点. 要求在有限步之内知道每一个点. 次数要求: 链的情况要求 \(O(n) ...

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

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

  7. [LibreOJ #2341]【WC2018】即时战略【交互】【LCT】

    Description 有一棵n个点的结构未知的树,初始时只有1号点是已被访问的. 你可以调用交互库的询问函数explore(x,y),其中x是已访问的点,y是任意点. 它会返回x向y方向走第一步的点 ...

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

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

  9. 「WC2018」即时战略

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

随机推荐

  1. js 时间延迟

    dojosetTimeout(dojo.hitch(this, function(){ this.onClickCount(); }), 3000); 普通应用在js中,延迟执行函数有两种,setTi ...

  2. Ubuntu, 更新Sourses.list

    1.备份原文件 sudo cp /etc/apt/sources.list /etc/apt/sources_list.bak 2.加载文件 vim:vim sourses.list ubuntu d ...

  3. JS jQuery 点击页面漂浮出文字

    看到有些网站点击页面任意地方都会弹出文字出来 感觉很炫酷 但其实实现方法很简单 哇哈哈哈~~~ // 调用 ( e, 消失毫秒, 数组, 向上漂浮距离) $(document).click(funct ...

  4. DVWA全级别之File Upload(文件上传)

    File Upload File Upload,即文件上传漏洞,通常是由于对上传文件的类型.内容没有进行严格的过滤.检查,使得攻击者可以通过上传木马获取服务器的webshell权限,因此文件上传漏洞带 ...

  5. 【音乐欣赏】《Abnormalize》 - 凛として時雨

    曲名:Abnormalize 作者:凛として時雨 [00:00.96]誰にも見せられないもの [00:06.44]頭の中溢れて [00:11.96]間違いさえも無い世界へ [00:17.16]迷い込ん ...

  6. js对象的深拷贝及其的几种方法

    深拷贝和浅拷贝是javascript中一个比较复杂的问题,也是面试官最喜欢问的问题之一,通过这个为可以看出是否入门,深拷贝和浅拷贝也是初学者经常犯错一个点. 简单来说深拷贝是拷贝储存在栈中的对象,而浅 ...

  7. VS“无法查找或打开PDB文件”是怎么回事?如何解决

    有时候,我们使用 VS(Visual Studio)编译程序时会出现“无法查找或打开PDB文件”的提示,并且此时程序会生成失败,无法运行,如下图所示: 大家不要惊慌,出现这种提示并不是代码写错了,而是 ...

  8. 十大常见web漏洞及防范

    十大常见web漏洞 一.SQL注入漏洞 SQL注入攻击(SQL Injection),简称注入攻击.SQL注入,被广泛用于非法获取网站控制权,是发生在应用程序的数据库层上的安全漏洞.在设计程序,忽略了 ...

  9. spring jdbcTemplate query 返回值为null

    spring jdbcTemplate query 返回值为null 今天使用以下方法从数据库中查询数据,返回列表 public List<BookBean> getBooks(){ St ...

  10. ServletContext的使用

    ServletContext: ServletContext表示Servlet应用程序.每个Web应用程序只有一个上下文.在将一个应用程序同时部署到多个容器的分布式环境中,每台Java虚拟机上的Web ...