「WC2018即时战略」
「WC2018即时战略」
题目描述
小 M 在玩一个即时战略 (Real Time Strategy) 游戏。不同于大多数同类游戏,这个游戏的地图是树形的。也就是说,地图可以用一个由 \(n\) 个结点,\(n - 1\) 条边构成的连通图来表示。这些结点被编号为 \(1 \sim n\)。
每个结点有两种可能的状态:“已知的”或“未知的”。游戏开始时,只有 \(1\) 号结点是已知的。
在游戏的过程中,小 M 可以尝试探索更多的结点。具体来说,小 M 每次操作时需要选择一个已知的结点 \(x\),和一个不同于 \(x\) 的任意结点 \(y\)(结点 \(y\) 可以是未知的)。然后游戏的自动寻路系统会给出 \(x\) 到 \(y\) 的最短路径上的第二个结点 \(z\),也就是从 \(x\) 走到 \(y\) 的最短路径上与 \(x\) 相邻的结点。此时,如果结点 \(z\) 是未知的,小 M 会将它标记为已知的。这个游戏的目标是:利用至多 \(T\) 次探索操作,让所有结点的状态都成为已知的。然而小 M 还是这个游戏的新手,她希望得到你的帮助。
解题思路 :
首先有一个比较直观的暴力,random_shuffle一个询问顺序,同时维护一棵“已知树”。
每次从根节点开始询问,回答要么是当前点的儿子,要么是一个未知节点,如果是当前点的儿子就进入儿子节点,否则就把未知节点添加进树。
这样子做复杂度和询问次数都是 \(O(n^2)\),加上一条链的暴力可以得到 \(65\) 分。
实际上每次如果是已知节点的话,只需要进入儿子对应的子树询问即可,所以很容易想到用点分树维护这个“已知树”,每次直接找到这个儿子对应的点分中心进行询问,树高变成 \(logn\) 。
但是加点操作会破坏点分树的性质,使得树高会大于 \(logn\) 以至于退化到平方级别的复杂度,在这里可以用替罪羊树的思想,每次加完点后暴力向上检查子树的平衡性暴力重构,\(\alpha\) 这里一般设 \(0.7\) 。
不过由于我维护点分树信息的时候用 \(map\) 存了每个儿子对应的点分中心是什么,所以我的复杂度是 $O(nlog^2n) $ ,有点卡常数,不保证所有地方都能过。
#include "rts.h"
/*program by mangoyang*/
#include<bits/stdc++.h>
#define inf (0x7f7f7f7f)
#define Max(a, b) ((a) > (b) ? (a) : (b))
#define Min(a, b) ((a) < (b) ? (a) : (b))
typedef long long ll;
using namespace std;
const int N = 1000005;
map<int, int> mp[N], ss[N];
int vis[N], vi[N], sz[N], in[N], cc[N], mx[N], fa[N];
int size[N], id[N], ps[N], all, mn, rt, Root = 1;
map<int, int>::iterator it;
namespace Line{
int s[2] = {1, 1};
inline void solve(int n){
for(int i = 1, x; i < n; i++){
int now = id[i], tw = 1;
while(!vis[now]){
x = explore(s[tw], now);
if(vis[x]) x = explore(s[tw^=1], now);
vis[x] = 1, s[tw] = x;
}
}
}
}
inline void cleartag(int u){
in[u] = 1;
for(map<int,int>::iterator it = mp[u].begin(); it != mp[u].end(); it++)
if(it->second) cleartag(it->second);
}
inline void getsize(int u, int ff){
int now = 0; sz[u] = 1;
for(map<int, int>::iterator it = mp[u].begin(); it != mp[u].end(); it++){
int v = it->first;
if(v == ff || !in[v]) continue;
getsize(v, u), sz[u] += sz[v];
if(sz[v] >= now) now = sz[v];
}
now = max(now, all - sz[u]);
if(now <= mn) mn = now, rt = u;
}
inline void rebuild(int u){
int last = all; in[u] = 0;
for(map<int, int>::iterator it = mp[u].begin(); it != mp[u].end(); it++){
int v = it->first;
if(!in[v]) continue;
mn = all = sz[v] >= sz[u] ? last - sz[u] : sz[v];
getsize(v, u);
size[rt] = all, fa[rt] = u, mx[u] = Max(mx[u], all);
mp[u][v] = rt, ss[u][rt] = v, mp[v][u] = 0, rebuild(rt);
}
}
inline void update(int u){
int ned = 0;
for(int x = u; x != Root; x = fa[x]){
size[fa[x]]++;
if(size[x] > mx[fa[x]]) mx[fa[x]] = size[x];
if(mx[fa[x]] >= size[fa[x]] * 0.735) ned = fa[x];
}
if(!ned) return;
if(ned){
cleartag(ned);
all = mn = size[ned], getsize(ned, fa[ned]);
if(ned == Root) Root = rt;
size[rt] = all, fa[rt] = fa[ned];
int k = ss[fa[rt]][ned];
ss[fa[rt]][rt] = k, mp[fa[rt]][k] = rt, rebuild(rt);
}
}
inline void addnode(int pos){
for(register int u = Root; ; ){
int x = explore(u, pos);
if(!vis[x]){
fa[x] = u, size[x] = vis[x] = 1;
mp[u][x] = ss[u][x] = x, mp[x][u] = 0, update(x);
break;
} u = mp[u][x];
}
}
void play(int n, int T, int datatype){
srand(19262333);
for(int i = 1; i < n; i++) id[i] = i + 1;
random_shuffle(id + 1, id + n), vis[1] = 1;
if(datatype == 3) return (void) (Line::solve(n));
for(int i = 1; i < n; i++) while(!vis[id[i]]) addnode(id[i]);
}
「WC2018即时战略」的更多相关文章
- [WC2018]即时战略——动态点分治(替罪羊式点分树)
题目链接: [WC2018]即时战略 题目大意:给一棵结构未知的树,初始时除1号点其他点都是黑色,1号点是白色,每次你可以询问一条起点为白色终点任意的路径,交互库会自动返回给你这条路径上与起点相邻的节 ...
- WC2018 即时战略
交互题 一棵树,一开始只有 1 号点是已知的,其他的都是未知的,你可以调用函数 explore(x,y) ,其中 x 必须是已知的,函数会找到 x 到 y 路径上第二个点,并把它标成已知,求最小步数使 ...
- 【UOJ#349】[WC2018] 即时战略
题目链接 题意 一开始已知一号点. 每次可以选定一个已知点和一个未知点,然后交互库会返回从已知点出发到达未知点路径上的第二个点. 要求在有限步之内知道每一个点. 次数要求: 链的情况要求 \(O(n) ...
- [WC2018]即时战略(LCT,splay上二分)
[UOJ题面]http://uoj.ac/problem/349 一道非常好的与数据结构有关的交互题. 首先先看部分分做法, 一上来我们肯定得钦定一个 \(explore\) 的顺序,直接随机就好. ...
- 「WC2018」即时战略
「WC2018」即时战略 考虑对于一条链:直接随便找点,然后不断问即可. 对于一个二叉树,树高logn,直接随便找点,然后不断问即可. 正解: 先随便找到一个点,问出到1的路径 然后找别的点,考虑问出 ...
- loj2341「WC2018」即时战略(随机化,LCT/动态点分治)
loj2341「WC2018」即时战略(随机化,LCT/动态点分治) loj Luogu 题解时间 对于 $ datatype = 3 $ 的数据,explore操作次数只有 $ n+log n $ ...
- 【WC2018】即时战略(动态点分治,替罪羊树)
[WC2018]即时战略(动态点分治,替罪羊树) 题面 UOJ 题解 其实这题我也不知道应该怎么确定他到底用了啥.只是想法很类似就写上了QwQ. 首先链的部分都告诉你要特殊处理那就没有办法只能特殊处理 ...
- 「WC2018」州区划分(FWT)
「WC2018」州区划分(FWT) 我去弄了一个升级版的博客主题,比以前好看多了.感谢 @Wider 不过我有阅读模式的话不知为何 \(\text{LATEX}\) 不能用,所以我就把这个功能删掉了. ...
- 【WC2018】即时战略
题目描述 小M在玩一个即时战略(Real Time Strategy)游戏.不同于大多数同类游戏,这个游戏的地图是树形的. 也就是说,地图可以用一个由 n个结点,n?1条边构成的连通图来表示.这些结点 ...
随机推荐
- [php]referer应用--http防盗链技术
1.防盗链的理解 所谓防盗链是防止其他的网站引用自己网站的资源连接,比如图片.视频等等,但是并不会阻碍从自己网站上享受资源的用户,这就要求能够将其他网站的连接请求阻止 2.防盗链的原理 其实从自己网站 ...
- java学习笔记记录
Java内存模型: Java虚拟机规范中将Java运行时数据分为六种. 1.程序计数器:是一个数据结构,用于保存当前正常执行的程序的内存地址.Java虚拟机的多线程就是通过线程轮流切换并分配处理器时间 ...
- [BZOJ 3039&洛谷P4147]玉蟾宫 题解(单调栈)
[BZOJ 3039&洛谷P4147]玉蟾宫 Description 有一天,小猫rainbow和freda来到了湘西张家界的天门山玉蟾宫,玉蟾宫宫主蓝兔盛情地款待了它们,并赐予它们一片土地. ...
- HNOI2019退役祭
对你没看错,是退役祭. Day -2 春游.话说为什么又是植物园? Day -1 白天上文化课,晚上给机房其它童鞋出题. Day 0 给他们考试,然后颓3Dmaze,毕竟没网 Day 1 车上复习了下 ...
- Tensorflow中使用TFRecords高效读取数据--结合Attention-over-Attention Neural Network for Reading Comprehension
原文链接:https://arxiv.org/pdf/1607.04423.pdf 本片论文主要讲了Attention Model在完形填空类的阅读理解上的应用. 转载:https://blog.cs ...
- perl6 Socket: 发送HTTP请求
sub MAIN(Str $host,Str $path, Int $port) { my $send = "GET $path HTTP/1.1\r\nHost: $host\r\n\r\ ...
- 如何将vmworkstation的虚机导成ovf模版
如何将vmworkstation的虚机导成ovf模版 最近碰见一个事情挺烦的苦恼了我好长一段时间,是这样的公司要进行攻防演练需要搭建一个owaps的靶站练手,环境我在我的电脑上已经搭好了(vmwork ...
- Linux下用到数据库sqlite3
最近在Linux下用到数据库sqlite3,于是开始了该方面的学习. 0. 引言 我们这篇文章主要讲述了如何在C/C++语言中调用 sqlite 的函数接口来实现对数据库的管理, 包括创建数据库.创建 ...
- ELK&ElasticSearch5.1基础概念及配置文件详解【转】
1. 配置文件 elasticsearch/elasticsearch.yml 主配置文件 elasticsearch/jvm.options jvm参数配置文件 elasticsearch/log4 ...
- 使用navicat for sqlserver 把excel中的数据导入到sqlserver数据库
以前记得使用excel向mysql中导入过数据,今天使用excel向sqlserver2005导入了数据,在此把做法记录一下 第一步:准备excel数据,在这个excel中有3个sheet,每个she ...