Solution -「JOISC 2021」古老的机器
\(\mathcal{Description}\)
Link.
这是一道通信题。
对于长度为一个 \(n\),仅包含字符 X, Y, Z 的字符串 \(s\),将其中 \(n\) 个字符按任意顺序删去,定义删除方案的权值为在子串 XYZ 中删除 Y 的次数。实现两个函数:
void Anna(int N, std::vector<char> S),获取字符串信息,传递不超过 \(7\times10^4\) 个01位用于通信;void Bruno(int N, int L, std::vector<int> A),获取通信信息,给出权值最大的删除方案。
\(n\le10^5\)。
\(\mathcal{Solution}\)
先看看怎么求最大权值。考虑当前最左侧 X 的位置 \(i\) 与最左侧 Z 的位置 \(j\),若 \(j<i\),显然删掉 \(j\) 无任何影响;否则考虑 \(i<k<j\),\(s_k\) 必然取 X 或 Y。那么从 \(j-1\) 逆序删除到 \(i+1\),最后删除掉 \(j\),继续迭代。容易(真的容易)看出这就是最大化权值的方案。
那么 Anna 需要告诉 Bruno 哪些信息呢?——唯一的一个 \(i\),和若干 \(j\)。一个小小的压缩方式是,对于连续的 Z,仅保留最右端的。特别地,在标记 X 的 \(1\) 的后面强制补一个 \(0\) 站位,我们就把信息串转化为长度为 \(n+1\),不存在连续 \(1\) 的数字串。每 \(W\) 为一段,利用 Fibonacci 数列求出每段的字典序编号,再转化为二进制输出,就能传递信息啦。
观察标称可知,取 \(W=63\),此时一段的总情况数接近 \(2^{44}\),损失较小。运算过程当然是 \(\mathcal O(n)\) 的,信息长度也就比 \(7\times10^4\) 少一百来次。
\(\mathcal{Code}\)
Anna.cpp
/* Clearink */
#include "Anna.h"
#include <vector>
#ifndef MY_REP_DEFINED
#define MY_REP_DEFINED
#define rep( i, l, r ) for ( int i = l, rep##i = r; i <= rep##i; ++i )
#define per( i, r, l ) for ( int i = r, per##i = l; i >= per##i; --i )
#endif
namespace {
typedef unsigned long long ULL;
const int MAXN = 1e5, W = 63, B = 44;
int n;
std::vector<char> s;
bool key[MAXN + W + 5];
ULL fib[W + 5];
inline void mark() {
int i = 0;
while ( i < n && s[i] != 'X' ) ++i;
key[i] = true;
for ( int j = i + 1; j < n; ++j ) {
while ( j < n && s[j] != 'Z' ) ++j;
while ( j + 1 < n && s[j + 1] == 'Z' ) ++j;
if ( i >= n || j >= n ) break;
key[j + 1] = true;
}
}
inline void encode() {
fib[0] = 1, fib[1] = 2;
rep ( i, 2, W ) fib[i] = fib[i - 1] + fib[i - 2];
for ( int l = 0; l <= n; l += W ) {
ULL msg = 0;
rep ( i, l, l + W - 1 ) if ( key[i] ) {
msg += fib[repi - i];
}
rep ( i, 0, B - 1 ) Send( msg >> i & 1 );
}
}
} // namespace.
void Anna( int n, std::vector<char> s ) {
::n = n, ::s = s;
mark(), encode();
}
Bruno.cpp
/* Clearink */
#include "Bruno.h"
#include <vector>
#ifndef MY_REP_DEFINED
#define MY_REP_DEFINED
#define rep( i, l, r ) for ( int i = l, rep##i = r; i <= rep##i; ++i )
#define per( i, r, l ) for ( int i = r, per##i = l; i >= per##i; --i )
#endif
namespace {
typedef long long ULL;
const int MAXN = 1e5, W = 63, B = 44;
ULL fib[W + 5];
int n;
std::vector<int> msg;
bool key[MAXN + W + 5];
inline void decode() {
fib[0] = 1, fib[1] = 2;
rep ( i, 2, W ) fib[i] = fib[i - 1] + fib[i - 2];
for ( int l = 0; l < msg.size(); l += B ) {
ULL val = 0;
per ( i, l + B - 1, l ) val = val << 1 | msg[i];
rep ( i, l / B * W, i + W - 1 ) {
if ( val >= fib[repi - i] ) {
key[i] = true, val -= fib[repi - i];
}
}
}
}
inline void solve() {
int i = 0;
while ( i < n && !key[i] ) Remove( i++ );
if ( i == n ) return ;
for ( int j = i + 1, las = i; j < n; ) {
while ( j < n && !key[j + 1] ) ++j;
per ( k, j - 1, las + 1 ) Remove( k );
if ( j < n ) Remove( las = j++ );
}
Remove( i );
}
} // namespace.
void Bruno( int n, int l, std::vector<int> msg ) {
::n = n, ::msg = msg;
decode(), solve();
}
Solution -「JOISC 2021」古老的机器的更多相关文章
- Solution -「JOISC 2021」「LOJ #3489」饮食区
\(\mathcal{Description}\) Link. 呐--不想概括题意,自己去读叭~ \(\mathcal{Solution}\) 如果仅有 1. 3. 操作,能不能做? ...
- Solution -「JOISC 2021」「LOJ #3495」聚会 2
\(\mathcal{Description}\) Link. 给定一棵含 \(n\) 个结点的树.称点集 \(S\) 到结点 \(u\) 的会合距离为 \(\sum_{v\in S}\ope ...
- Solution -「JOISC 2021」「LOJ #3491」道路建设
\(\mathcal{Description}\) Link. 平面上有 \(n\) 个互不重合的点 \((x_{1..n},y_{1..n})\),求其两两曼哈顿距离的前 \(m\) 小值. ...
- Solution -「NOI 2021」「洛谷 P7740」机器人游戏
\(\mathcal{Description}\) Link. 自己去读题面叭~ \(\mathcal{Solution}\) 首先,参悟[样例解释 #2].一种暴力的思路即为钦定集合 \ ...
- Solution -「JOISC 2020」「UOJ #509」迷路的猫
\(\mathcal{Decription}\) Link. 这是一道通信题. 给定一个 \(n\) 个点 \(m\) 条边的连通无向图与两个限制 \(A,B\). 程序 Anthon ...
- Solution -「NOIOL-S 2021」「洛谷 P7470」岛屿探险
\(\mathcal{Description}\) Link. 给定序列 \(\{(a,b)_n\}\),\(q\) 组形如 \((l,r,c,d)\) 的询问,求 \[\Big|\{i\in ...
- Solution -「JOISC 2019」「LOJ #3036」指定城市
\(\mathcal{Description}\) Link. 给定一棵含 \(n\) 个结点的树,双向边权不相同.\(q\) 次询问,每次询问在树上标记 \(e\) 个点,标记的价值为所有趋 ...
- Solution -「ARC 104E」Random LIS
\(\mathcal{Description}\) Link. 给定整数序列 \(\{a_n\}\),对于整数序列 \(\{b_n\}\),\(b_i\) 在 \([1,a_i]\) 中等概率 ...
- Solution -「简单 DP」zxy 讲课记实
魔法题位面级乱杀. 「JOISC 2020 Day4」治疗计划 因为是不太聪明的 Joker,我就从头开始理思路了.中途也会说一些和 DP 算法本身有关的杂谈,给自己的冗长题解找借口. 首先,治疗方案 ...
随机推荐
- navicat 找不到系统路径 【修改了系统路径中文名称引起的】
这是我还没修改系统路径中文名称时的路径, 怎么办? 关闭当前用户连接 右键,选择连接属性 把那个改了即可
- VMware 创建的虚拟机,Xshell无法进行连接
使用场景: 在VMware 创建了Centos7后,Xshell一直连接不上,如果排查以下问题还是不行.就可以用这种方法了 1.配置了静态地址 2.VMware配置了NAT映射,划分了网段后 3.检查 ...
- 小程序canvas绘制纯色圆角区域 setdata数组某一项
小程序canvas绘制纯色圆角区域: //方法: roundRectPath:function(ctx, x, y, w, h, r) { ctx.beginPath(); ctx.moveTo(x ...
- 只需两步在Linux系统安装百度网盘--Ubuntu20
Linux Ubuntu系统安装百度网盘 百度网盘已支持Linux系统下载和使用.使用Linux系统下载并安装一个百度网盘是非常简单的,只需要以下两个步骤: 第一步 进入官网下载.deb类型的百度网盘 ...
- Python网络编程之网络基础
Python网络编程之网络基础 目录 Python网络编程之网络基础 1. 计算机网络发展 1.1. OSI七层模型 1.2. 七层模型传输数据过程 2. TCP/IP协议栈 2.1 TCP/IP和O ...
- 《手把手教你》系列技巧篇(五十七)-java+ selenium自动化测试-下载文件-下篇(详细教程)
1.简介 前边几篇文章讲解完如何上传文件,既然有上传,那么就可能会有下载文件.因此宏哥就接着讲解和分享一下:自动化测试下载文件.可能有的小伙伴或者童鞋们会觉得这不是很简单吗,还用你介绍和讲解啊,不说就 ...
- Java不限制从键盘输入一个数组
Java不限制从键盘输入一个数组 在写算法的时候,需要从键盘输入一个数组,一直不会,最近看了几篇博客学会了,下面用二分查找举例: package com.基础; import java.util.Sc ...
- 洛谷 CF196A 题解
题目传送门 题目描述: 读入字符串,求该串的最大字典序子序列. 我的思路: 循环判断只要当前字符比后面所有的字符的字典序大,就把这个字符存到另一个字符串中,最后和输入的字符串循环比较如果该字符和输入时 ...
- Three.js之绘制物体的边框及修改lineWidth
本博文主要记录如何使用three.js绘制物体的边框及修改其lineWidth.three.js是个技术点比较多,查询资料又比较少的框架,单单就这个修改lineWidth就是一个坑.先放一个动态的效果 ...
- Cesium入门13 - Extras - 附加内容
Cesium入门13 - Extras - 附加内容 Cesium中文网:http://cesiumcn.org/ | 国内快速访问:http://cesium.coinidea.com/ 剩下的代码 ...