当$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]位移寄存器的更多相关文章

  1. 【C51】单片机芯片之——图解74HC595

    第一部部分用于快速查阅使用,详细的使用见文章第二部分 引脚图

  2. DES加解密算法Qt实现

      算法解密qt加密table64bit [声明] (1) 本文源码 大部分源码来自:DES算法代码.在此基础上,利用Qt编程进行了改写,实现了DES加解密算法,并添加了文件加解密功能.在此对署名为b ...

  3. DES加密模式详解

    DES加密模式详解 http://www.cnblogs.com/Lawson/archive/2012/05/20/2510781.html http://www.blogjava.net/wayn ...

  4. 1.3 CPU简介

    目录 CPU的功能模块 cpu总线 CPU寄存器 16位cpu的寄存器组 32位cpu的寄存器组 64位cpu的寄存器组 CPU的功能模块 CPU从逻辑上可以划分成3个模块,分别是控制单元.运算单元和 ...

  5. N76E003之SPI

    串行外围总线 (SPI)N76E003系列提供支持高速串行通信的SPI模块.SPI 为微控制与外设 EEPROM, LCD 驱动, D/A 转换之间提供全双工.高速.同步传输的总线.可提供主机从机模式 ...

  6. stm32 SPI介绍和配置

    SPI是一种高速的,全双工同步的通信总线,在芯片管脚上占用了四根线,节约了芯片的管脚,同时为PCB的布局节省了空间,提供了方便,因此越来越多的芯片集成了这种通信协议,STM32也就有了SPI接口. 有 ...

  7. 如何用 JavaScript 控制 Arduino?

    Arduino 运行 C 语言,而主控端运行 JavaScript,一次要编写和维护两种程序.既然浏览器和服务器都用 JavaScript,若 Arduino 也能用 JavaScript 控制,那岂 ...

  8. Java 加解密技术系列之 DES

    序 前几篇文章讲的都是单向加密算法.当中涉及到了 BASE64.MD5.SHA.HMAC 等几个比較常见的加解密算法. 这篇文章,以及后面几篇.打算介绍几个对称加密算法.比方:DES.3DES(Tri ...

  9. TLC5615

    #include <reg51.h> #include "TLC5615.c" code uchar seven_seg[] = {0xc0, 0xf9, 0xa4, ...

随机推荐

  1. MyBatis 批量插入数据的 3 种方法!

    批量插入功能是我们日常工作中比较常见的业务功能之一,之前我也写过一篇关于<MyBatis Plus 批量数据插入功能,yyds!>的文章,但评论区的反馈不是很好,主要有两个问题:第一,对 ...

  2. 开启Nginx代理HTTPS功能

    1.首先查看是否已经安装SSL openssl version -a 2.生成SSL证书 在nginx目录下创建ssl文件夹 cd /etc/pki mkdir nginx cd nginx 生成20 ...

  3. bzoj2064分裂(dp)

    题目大意: 给定一个初始集合和目标集合,有两种操作:1.合并集合中的两个元素,新元素为两个元素之和 2.分裂集合中的一个元素,得到的两个新元素之和等于原先的元素.要求用最小步数使初始集合变为目标集合, ...

  4. FastAPI 学习之路(十六)Form表单

    系列文章: FastAPI 学习之路(一)fastapi--高性能web开发框架 FastAPI 学习之路(二) FastAPI 学习之路(三) FastAPI 学习之路(四) FastAPI 学习之 ...

  5. docker内服务访问宿主机服务

    目录 1. 场景 2. 解决 4. 参考 1. 场景 使用windows, wsl2 进行日常开发测试工作. 但是wsl2经常会遇到网络问题.比如今天在测试一个项目,核心功能是将postgres 的数 ...

  6. 【UE4】GamePlay架构

    新标签打开或者下载看大图 更新: 增加 编程子系统 Subsystem 思维导图 Character pipeline

  7. 安装多个版本的MySQL

    安装多个版本的MySQL 之前在PC机上安装了 MySQL 5.5 后续发现了窗口函数,而窗口函数是 MySQL8 以后才支持的,故在本地又安装了一个 MySQL 8 安装MySQL 5.5 进入my ...

  8. JAVA的array中indexOf

    记得龙哥有个重构的文章里说直接判断啥的. 今天看JDK ArrayList,看到了他的 indexOf,他先判断,后进入循环,看似写了两遍for 循环,但是简单明了暴力.i like it . pub ...

  9. OO第二单元——多线程(电梯)

    OO第二单元--多线程(电梯) 综述 第二单元的三次联系作业都写电梯,要求逐步提高,对于多线程的掌握也进一步加深.本次作业全部都给出了输入输出文件,也就避免了正则表达式判断输入输出是否合法的问题. 第 ...

  10. 你知道怎么从jar包里获取一个文件的内容吗

    目录 背景 报错的代码 原先的写法 编写测试类 找原因 最终代码 背景 项目里需要获取一个excle文件,然后对其里的内容进行修改,这个文件在jar包里,怎么尝试都读取不成功,但是觉得肯定可以做到,因 ...