【IOI2018】机械娃娃

看到的时候感到很不可做,因为所有的开关都要状态归零。因此可以得到两分的好成绩。

……然后 yhx-12243 说:这不是线段树优化建图吗?

于是我获得了启发,会做了……

还不是和上次一样,通过提示做出这种交互题的?

我还是太菜了

以下魔改自我的思考过程(一开始想对每一个触发器配一组开关决策下一步,然后听说用线段树直接想到一组开关决策整颗树了)

其实前半部分的思考貌似没用,直接套到整棵树上是适用的



因为状态要清零,考虑清空这个状态。

考虑每个触发器连向一个开关,来决策下一步走什么,因为和二进制有关,所以我们构造一个线段树类似的。

假设出现 \(s\) 次,记 \(L = 2^k \geq s\) 使得 \(k\) 最小。

那么我们前 \(L - s\) 次就开个到根的边,后面 \(s\) 次就可以直接走后继了。

那么如果走了 \(L\) 步,线段树内所有点都遍历到了。

注意到 \(L\) 是二的幂,跑完后所有非叶节点区间长度都是偶数,即遍历到偶数次,即清零了。这也说明了为什么不用普通线段树。

所以要把叶子结点全部扔掉,不然就会有节点只遍历到一次。如果扔掉叶子,那么就是一棵大小为 \(L - 1\) 的树。

注意特判一下最后一个点的后继是 \(0\)。

这样点数是 \(2n\) 的 (对于一个 \(s\),有 \(s \leq L < 2s\)),可以获得 \(50\) 分。

考虑优化这个,发现很多的点是没有用的,即整个区间都会再次回到根。那么要访问到这个区间的时候,不如提前回到根。即删掉这个点,父亲连向自己的边改为连向根。

但是发现优化力度不大,这是因为这道题的遍历方式使得遍历的点交错了起来。

因为最后一个点是在右边的,那么我们把线段树右边的那 \(s\) 个点取来,钦定它们是出边,然后根据先前遍历的顺序把值钦定一下就好。

我们只选了右边的点,优化力度很明显了。

对于 \(s = 5\), \(L = 8\),淡色是叶子,打钩的是有用的点。(机房没带数位板请见谅,其他软件不会用,求dalao推荐)

可以证明对于一个 \(N\) ,点数是 \(N - 1 + \lceil \log_2 N \rceil\)。考虑对于相同的 \(L\), 考虑 \(N\) 个叶子,至少要 \(N - 1\) 个点,而多出来的是单独一条链,也就是最后一个元素向上的链。这个链长度小于等于 \(\lceil \log_2 N \rceil\)。

所以这样子就能得到较为优秀的分数了。

然而对于每一个触发器,我们都会多一个 \(\log\)。那么为什么不放在一起呢?这样正好符合正解的复杂度。

考虑用一个统一的开关线段树维护这些触发器,然后触发器回到决策线段树的开头。

注意触发器不能回到起点,因为一个触发器可能出现多次,那么我们很难决定它是最后一个的时候怎么做。

为了回到起点,我们增加一个虚点,或者换句话说,就是往规定的触发器序列末尾加一个 \(0\)。

和上面的方法类似,我们把叶子的遍历序列存下来,同时只取在线段树右边的 \(N + 1\) 个点,根据遍历的时间来钦定触发器。

一样的,因为遍历了二的幂次,所以所有开关归零,经过开关次数 \(O\left(N \log N\right)\) 大概 \(3 \times 10^6\),也不会爆炸。

开关个数 \(O\left(N + \lceil \log_2 \left(N + 1\right) \rceil\right)\),因为judger对这个 \(\log\) 的界卡的不紧,大概可以大 \(1\),所以刚好能通过此题。

看到有些人用bitreverse,的确这样子就是bitreverse后的不断+1,可以给各种操作带来方便。

#include "doll.h"
#include <bits/stdc++.h>

typedef std::vector<int> VI;
const int MAXN = 262145;
const int spe = 19260817;
int idx[MAXN], xs[MAXN], ys[MAXN];
int qli[MAXN];
int typ[MAXN], cnto[MAXN], tot, lim, N;
int tli[MAXN], t0t, cnt[MAXN];
void qry(int u, int l, int r) {
    if (l == r) {
        cnto[l] = ++tot;
        return ;
    }
    int mid = l + r >> 1;
    !typ[u] ? qry(u << 1, l, mid) : qry(u << 1 | 1, mid + 1, r);
    typ[u] ^= 1;
}
void relable(int u, int l, int r) {
    if (l == r) {
        tli[++t0t] = l;
        return ;
    }
    int mid = l + r >> 1;
    relable(u << 1 | 1, mid + 1, r);
    relable(u << 1, l, mid);
}
int txt;
int build(int l, int r) {
    if (l == r) {
        int now = cnt[l];
        return now > 0 ? qli[now] : spe;
    }
    int mid = l + r >> 1;
    int tl = build(l, mid), tr = build(mid + 1, r);
    if (tl == spe && tr == spe) return spe;
    int now = ++txt;
    xs[now] = tl, ys[now] = tr;
    return -now;
}
void create_circuit(int M, VI A) {
    N = A.size(); ++N;
    lim = 1;
    while (lim < N) lim <<= 1;
    for (int i = 1; i <= lim; ++i) qry(1, 1, lim);
    relable(1, 1, lim);
    std::sort(tli + 1, tli + 1 + N, [] (int a, int b) { return cnto[a] < cnto[b]; });
    for (int i = 1; i <= N; ++i)
        cnt[tli[i]] = i;
    std::copy(A.begin(), A.end(), qli + 1);
    VI C(M + 1, 0), X, Y;
    int rt = build(1, lim);
    for (int i = 1; i <= txt; ++i) {
        xs[i] == spe ? xs[i] = rt : 0;
        ys[i] == spe ? ys[i] = rt : 0;
    }
    for (int i = 0; i <= M; ++i) C[i] = rt;
    X.assign(xs + 1, xs + 1 + txt);
    Y.assign(ys + 1, ys + 1 + txt);
    answer(C, X, Y);
}

原文地址:https://www.cnblogs.com/daklqw/p/11645788.html

时间: 2024-10-11 05:44:28

【IOI2018】机械娃娃的相关文章

机械随笔(y一)

过去最巧秒的机械往往是机械对机械自身的控制,然而现在往往只要一块电路板就行了(有点无奈). 可爱可畏的机电一体化. 人类社会第一个巨大进步,效率生产力的极大提高,人口的井喷来自工业革命,来自对钢铁肌肉的力量的首次挖掘利用.而今全球互联网的沟通促成的信息无限交流并未最大限度地提升人类生产力(更不用说某些的商业方面的模式创新).信息的交流是为生产力的提升打下坚实基础,当然强大的云计算也应该是未来生产变革中不可或缺的一环.最终的发展仍然要落实到制造的本体上,毕竟现在的人不可能靠数据流生活,很长很长一段

机械设计 AutoCAD2010视频教程 Pro/E4视频教程 UG5.0视频教程 solidworks2010视频教程

热门推荐电脑办公计算机基础知识教程 Excel2010基础教程 Word2010基础教程 PPT2010基础教程 五笔打字视频教程 Excel函数应用教程 Excel VBA基础教程 WPS2013表格教程 更多>平面设计PhotoshopCS5教程 CorelDRAW X5视频教程 Photoshop商业修图教程 Illustrator CS6视频教程 更多>室内设计3Dsmax2012教程 效果图实例提高教程 室内设计实战教程 欧式效果图制作实例教程 AutoCAD2014室内设计 Aut

最好用的几款机械键盘品牌旗舰店推荐

新用户购买机械键盘需要了解什么? 传统的机械键盘曾被物美价廉的薄膜键盘所替代,而当前的机械键盘主要是面对电竞行业.游戏行业以及有大量打字输入需求的人群的,比 如游戏玩家.编辑和码农一类的.同时在模具.材质.轴.结构还是价格.功能等方面上,也与传统的机械键盘有些区别. 机械键盘的优点与缺点 优点很显著,寿命长,按键手感很舒服. 缺点也很突出,就价格贵,不过听说即使是价格贵,码农发烧友都喜欢这种欧. 为什么机械键盘价格差异那么大? 了解轴之后再来谈谈,为什么机械键盘的价格会有百元与千元之间的差距,即

机械节能产品生产企业网站织梦模板【dedecms模板】

模板名称:机械节能产品生产企业网站织梦模板模板介绍:页面简洁简单,容易管理,DEDE5.5内核以上都可以使用:附带测试数据! 模板特点:适合机械电子产品,电子科技类,机械网站类企业网站使用,简单便捷,易于管理,一款值得拥有的织梦网站模板.简洁美观大方的设计风格,图片展示效果绝佳.页面结构简单,利于SEO的优化,模板后台易于管理. 使用程序:织梦DEDECMS5.5以上版本都可以使用. 模板页面:index.htm 首页模板head.htm 头部模板footer.htm 底部模板article_a

从零DIY机械键盘/主控方案

自从有了第一套机械键盘,先后修改了接口方案,安装了LED灯等,但是始终无法满足自己的DIY欲望. 于是想到最简单的方法就是用现成的主控,而主控来源于废弃的键盘,如下图: 这种主控也是矩阵方式,只需要测出需要的相应键位然后焊接好就行,完成图如下 采用了o 5脚红轴机械轴..玩lol的朋友应该熟悉这些键位~ 但是我仍然想做一个60/88/104的键盘,同时能够自己编程写入不同的组合键 实现不同的功能,甚至可以实现全键无冲. 使用现成的主控方案完全不能满足以上想法,于是就打算自己从主控开始. 关于ke

各种机械键盘轴的区别,到底什么轴好

http://www.pcviva.com/jixiejianpanshenmezhouhao.html 如果你已经清楚什么是机械键盘,也阅读了<机械键盘什么牌子好>这篇文章,你可能要挑的,就是机械键盘的轴了.机械键盘什么轴好呢,我们先看下机械键盘的白轴.黑轴.青轴.茶轴.红轴的区别.  (在多数情况下,PC万岁所说“机械键盘轴”都指Cherry MX轴.) 机械键盘轴的区别(概览) 机械键盘轴的区别: 白轴操作压力克数比黑轴大段落感比茶轴强已停产 黑轴操作压力:58.9g±14.7g没有段落

程序的机械级表示学习记录

程序的机械级表示学习记录 X86的三代寻址方式 DOS时代的平坦模式,不区分用户空间和内核空间,很不安全. 8086的分段模式. IA32的带保护模式的平坦模式. 对于机械级编程的两种重要抽象 ISA:机械级程序的格式和行为,定义为指令集体系结构,它定义了处理器状态.指令的格式,以及每条指令对状态的影响. 虚拟地址:机器级程序使用的存储器地址,提供的存储器模型看上去是一个非常大的数组.存储器系统的实际实现是将多个硬件存储器和操作系统软件组合起来的. 在GCC中获得汇编代码与反汇编 获得汇编代码:

纸娃娃系统再次增强

一个引擎,纸娃娃系统是重中之重,她不光承载着上下协调的关系,比如舞台,精灵等一系列以树结构为渲染层次组织架构的一种基础实现,同时也是更为强大的骨骼动画系统的基石.先前实现的不够稳定高效,这次大规模重构和Review顺便做了个彻底改造,新的代码无论结构层次,易读性清晰性以及运行效率,稳定性上都上升了一个数量级.好的功能实现就是不断的迭代实现,自己的代码已经迭代了10几次,有几次几乎是全部堆倒重来,唯有偏痴才能做精.(坏处是不能容忍自己的产品的瑕疵导致猴年马月都发布不了).非常鄙视那些为了吸引眼球只

机械革命 USB装系统各种坑

买了个号称超强性价比的游戏本- 机械革命, i7+ssd+hd+4G RAM+ GTX850M, 很直接, 直接出厂就一个DOS系统,回来要自己装机. 好吧, 先下了个大白菜软件,用来刻录ISO系统到USB盘上, 为啥用USB呢? 其实我手头好几个光盘, 但这机子没有光驱... 所以,这就是悲剧的开始. usb引导进入win7安装界面,选了自定义安装后, 提示"缺少所需的cd/dvd驱动器设备驱动程序", 找了半天问题, 又换了个ISO重做了USB的启动盘,无果. 后来网上狂搜,发现可