[loj3528]位移寄存器
当$s=0$时(求最小值):
若$x_{0},x_{1},...,x_{n-1}$和$y_{0},y_{1},...,y_{n-1}$像题中所给的方式存储在$r[0][0..nk-1]$和$r[1][0..nk-1]$,那么执行
not(2,1),add(2,0,2),xor(2,0,2),xor(2,1,2),right(2,2,k)
store(3,[1,0,0,...,0,1,0,0,...,0,......]),and(2,2,3)
left(3,2,1),or(2,2,3)
left(3,2,2),or(2,2,3)
……
left(3,2,2^{L-2}),or(2,2,3)
left(3,2,k-2^{L-1}),or(2,2,3)
not(3,2),and(2,0,2),and(3,1,3),or(0,2,3)
(其中第2行$store$中1的位置为所有$k$的倍数,第7行$L=\lceil\log_{2}k\rceil$)
即可将$\min(x_{i},y_{i})$像题中所给的方式存储在$r[0][0..nk-1]$
操作次数为$2L+11$,预处理第二步$store$,当$k=10$时为$18+1$(后者的1指全局)
由此进行分治,即每一次将前$\lceil\frac{n}{2}\rceil$个和后$\lceil\frac{n}{2}\rceil$个取$\min$使得$n'=\lceil\frac{n}{2}\rceil$,直至$n=1$即为答案
操作次数为$19\lceil\log_{2}n\rceil+1$,当$n=100$时为134,可以通过
当$s=1$时(排序):
类似前面取$\min$,我们可以构造"检查-交换"操作,只需要将最后一行修改为
not(3,2),and(4,0,2),and(5,1,3),and(6,0,3),and(7,1,2),or(0,4,5),or(1,6,7)
即可将$\min(x_{i},y_{i})$存储在$r[0][0...nk-1]$,将$\max(x_{i},y_{i})$存储在$r[1][0..nk-1]$
操作次数为$2L+14$,预处理第二步$store$,当$k=10$时为21+1
由于要先确定交换的位置(而不是根据数值交换),那么通常的排序算法中只有冒泡和选择可以支持,但两者的交换次数都为$o(n^{2})$,无法通过
注意到上述过程支持同时交换多个不同的数,此时有一个更为优秀的奇偶移项排序,伪代码如下:
i=1..(n+1)/2
j=1..n/2 swap(a[2j-1],a[2j])
j=1..(n-1)/2 swap(a[2j],a[2j+1])
(其中$a_{i}$下标从1到$n$,/2都指下取整,swap指"检查-交换"操作)
两次$j$的循环,实际上都可以用一次交换代替,那么交换次数即降为$o(n)$
具体实现,只需要将奇数位和偶数位分别取出,并且高位要补0避免0被交换到较小处
操作次数为$48\lceil\frac{n+1}{2}\rceil+5$,当$n=100$时为2405,可以通过
1 #include<bits/stdc++.h>
2 #include"registers.h"
3 using namespace std;
4 #define B 2000
5 int n,k,L;
6 void get_min(){
7 append_not(2,1);
8 append_add(2,0,2);
9 append_xor(2,0,2);
10 append_xor(2,1,2);
11 append_right(2,2,k);
12 append_and(2,2,99);
13 for(int i=0;i<L-1;i++){
14 append_left(3,2,(1<<i));
15 append_or(2,2,3);
16 }
17 if (L)append_left(3,2,k-(1<<L-1));
18 append_or(2,2,3);
19 append_not(3,2);
20 append_and(2,0,2);
21 append_and(3,1,3);
22 append_or(0,2,3);
23 }
24 void swap(int x,int y){
25 append_not(2,1);
26 append_add(2,0,2);
27 append_xor(2,0,2);
28 append_xor(2,1,2);
29 append_right(2,2,k);
30 append_and(2,2,99);
31 for(int i=0;i<L-1;i++){
32 append_left(3,2,(1<<i));
33 append_or(2,2,3);
34 }
35 if (L)append_left(3,2,k-(1<<L-1));
36 append_or(2,2,3);
37 append_not(3,2);
38 append_and(4,0,2);
39 append_and(5,1,3);
40 append_and(6,0,3);
41 append_and(7,1,2);
42 append_or(x,4,5);
43 append_or(y,6,7);
44 }
45 void calc0(){
46 for(;n>1;n=((n+1)>>1)){
47 append_right(1,0,(n>>1)*k);
48 get_min();
49 }
50 }
51 void calc1(){
52 vector<bool>v,v0,v1;
53 for(int i=0;i<B;i++)v.push_back((n*k<=i));
54 append_store(98,v);
55 append_or(0,0,98);
56 for(int i=0;i<B;i++)v0.push_back(((i/k)&1)^1);
57 for(int i=0;i<B;i++)v1.push_back(((i/k)&1));
58 append_store(96,v0);
59 append_store(97,v1);
60 for(int i=1;i<=((n+1)>>1);i++){
61 append_and(1,0,97);
62 append_right(1,1,k);
63 append_and(0,0,96);
64 swap(0,1);
65 append_left(1,1,(k<<1));
66 swap(1,0);
67 append_right(1,1,k);
68 append_or(0,0,1);
69 }
70 }
71 void construct_instructions(int p,int nn,int kk,int q){
72 n=nn,k=kk,L=0;
73 while ((1<<L)<k)L++;
74 vector<bool>v;
75 for(int i=0;i<B;i++)v.push_back(i%k==0);
76 append_store(99,v);
77 if (!p)calc0();
78 else calc1();
79 }
[loj3528]位移寄存器的更多相关文章
- 【C51】单片机芯片之——图解74HC595
第一部部分用于快速查阅使用,详细的使用见文章第二部分 引脚图
- DES加解密算法Qt实现
算法解密qt加密table64bit [声明] (1) 本文源码 大部分源码来自:DES算法代码.在此基础上,利用Qt编程进行了改写,实现了DES加解密算法,并添加了文件加解密功能.在此对署名为b ...
- DES加密模式详解
DES加密模式详解 http://www.cnblogs.com/Lawson/archive/2012/05/20/2510781.html http://www.blogjava.net/wayn ...
- 1.3 CPU简介
目录 CPU的功能模块 cpu总线 CPU寄存器 16位cpu的寄存器组 32位cpu的寄存器组 64位cpu的寄存器组 CPU的功能模块 CPU从逻辑上可以划分成3个模块,分别是控制单元.运算单元和 ...
- N76E003之SPI
串行外围总线 (SPI)N76E003系列提供支持高速串行通信的SPI模块.SPI 为微控制与外设 EEPROM, LCD 驱动, D/A 转换之间提供全双工.高速.同步传输的总线.可提供主机从机模式 ...
- stm32 SPI介绍和配置
SPI是一种高速的,全双工同步的通信总线,在芯片管脚上占用了四根线,节约了芯片的管脚,同时为PCB的布局节省了空间,提供了方便,因此越来越多的芯片集成了这种通信协议,STM32也就有了SPI接口. 有 ...
- 如何用 JavaScript 控制 Arduino?
Arduino 运行 C 语言,而主控端运行 JavaScript,一次要编写和维护两种程序.既然浏览器和服务器都用 JavaScript,若 Arduino 也能用 JavaScript 控制,那岂 ...
- Java 加解密技术系列之 DES
序 前几篇文章讲的都是单向加密算法.当中涉及到了 BASE64.MD5.SHA.HMAC 等几个比較常见的加解密算法. 这篇文章,以及后面几篇.打算介绍几个对称加密算法.比方:DES.3DES(Tri ...
- TLC5615
#include <reg51.h> #include "TLC5615.c" code uchar seven_seg[] = {0xc0, 0xf9, 0xa4, ...
随机推荐
- MyBatis 批量插入数据的 3 种方法!
批量插入功能是我们日常工作中比较常见的业务功能之一,之前我也写过一篇关于<MyBatis Plus 批量数据插入功能,yyds!>的文章,但评论区的反馈不是很好,主要有两个问题:第一,对 ...
- 开启Nginx代理HTTPS功能
1.首先查看是否已经安装SSL openssl version -a 2.生成SSL证书 在nginx目录下创建ssl文件夹 cd /etc/pki mkdir nginx cd nginx 生成20 ...
- bzoj2064分裂(dp)
题目大意: 给定一个初始集合和目标集合,有两种操作:1.合并集合中的两个元素,新元素为两个元素之和 2.分裂集合中的一个元素,得到的两个新元素之和等于原先的元素.要求用最小步数使初始集合变为目标集合, ...
- FastAPI 学习之路(十六)Form表单
系列文章: FastAPI 学习之路(一)fastapi--高性能web开发框架 FastAPI 学习之路(二) FastAPI 学习之路(三) FastAPI 学习之路(四) FastAPI 学习之 ...
- docker内服务访问宿主机服务
目录 1. 场景 2. 解决 4. 参考 1. 场景 使用windows, wsl2 进行日常开发测试工作. 但是wsl2经常会遇到网络问题.比如今天在测试一个项目,核心功能是将postgres 的数 ...
- 【UE4】GamePlay架构
新标签打开或者下载看大图 更新: 增加 编程子系统 Subsystem 思维导图 Character pipeline
- 安装多个版本的MySQL
安装多个版本的MySQL 之前在PC机上安装了 MySQL 5.5 后续发现了窗口函数,而窗口函数是 MySQL8 以后才支持的,故在本地又安装了一个 MySQL 8 安装MySQL 5.5 进入my ...
- JAVA的array中indexOf
记得龙哥有个重构的文章里说直接判断啥的. 今天看JDK ArrayList,看到了他的 indexOf,他先判断,后进入循环,看似写了两遍for 循环,但是简单明了暴力.i like it . pub ...
- OO第二单元——多线程(电梯)
OO第二单元--多线程(电梯) 综述 第二单元的三次联系作业都写电梯,要求逐步提高,对于多线程的掌握也进一步加深.本次作业全部都给出了输入输出文件,也就避免了正则表达式判断输入输出是否合法的问题. 第 ...
- 你知道怎么从jar包里获取一个文件的内容吗
目录 背景 报错的代码 原先的写法 编写测试类 找原因 最终代码 背景 项目里需要获取一个excle文件,然后对其里的内容进行修改,这个文件在jar包里,怎么尝试都读取不成功,但是觉得肯定可以做到,因 ...