当$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. vite首次启动加载慢

    背景 随着vue3的到来,vite开始被各大vue3组件库使用,公司开始一个新项目,准备尝试用vite试一波. 问题发现 当把公司新项目移植到vite后,启动非常快,但发现页渲染时间慢了很多 可以看到 ...

  2. 都 2021 年了,Serverless 能取代微服务吗?

    来源 | Serverless 公众号 编译 | OrangeJ 作者 | Mariliis Retter "Serverless 能取代微服务吗?" 这是知乎上 Serverle ...

  3. Java JDK的下载与安装!Java基础

    在了解什么是Java.Java 语言的特点以及学习方法之后,本节将介绍如何搭建编写 Java 程序所需要的开发环境--JDK,只有搭建了环境才能敲代码! 学Java的都知道,JDK 是一种用于构建在 ...

  4. uoj167 元旦老人与汉诺塔(记忆化搜索)

    QwQ太懒了,题目直接复制uoj的了 QwQ这个题可以说是十分玄学的一道题了 首先可以暴搜,就是\(dfs\)然后模拟每个过程是哪个柱子向哪个柱子移动 不多解释了,不过实现起来还是有一点点难度的 直接 ...

  5. 3D渲染

    3d渲染的本质是在三维坐标系中绘制很三角形,用三角形拼成物体,然后投影到二维图像上,所以做渲染就是画好这些三角形;3d渲染输入的是很多三角形的3个顶点和属性,输出的是一张2d图.画好三角形要研究给三角 ...

  6. NX Open 图层说

    我也是偶然发现的,在一次调试下,竟然会报警. 所以我写了测试代码,进行测试:结果如下 纳尼???还有271层?还能设置大于256层?NX open可以的.

  7. Spark分区器浅析

    分区器作用:决定该数据在哪个分区 概览: 仅仅只有pairRDD才可能持有分区器,普通RDD的分区器为None 在分区器为None时RDD分区一般继承至父RDD分区 初始RDD分区数: 由集合创建,R ...

  8. filebeat收集日志到elsticsearch中并使用ingest node的pipeline处理

    filebeat收集日志到elsticsearch中 一.需求 二.实现 1.filebeat.yml 配置文件的编写 2.创建自定义的索引模板 3.加密连接到es用户的密码 1.创建keystore ...

  9. SpringBoot整合Prometheus

    SpringBoot整合Prometheus 一.需求 二.实现步骤 1.引入jar包 2.application.prometheus文件配置 3.查看指标数据 4.接入到 prometheus 中 ...

  10. csp总结 (差点爆零的总结)

    T1,iterator忘了怎么写了,想了很久都想不出来有什么可以替代,只好O(n^2): T2,不会,只会打暴力 T3,自以为是正解,写了很久大概3h,却一直过不了大样例,大样例输出全是0: T4,不 ...