• [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=lceillog_{2}k ceil$)

    即可将$min(x_{i},y_{i})$像题中所给的方式存储在$r[0][0..nk-1]$

    操作次数为$2L+11$,预处理第二步$store$,当$k=10$时为$18+1$(后者的1指全局)

    由此进行分治,即每一次将前$lceilfrac{n}{2} ceil$个和后$lceilfrac{n}{2} ceil$个取$min$使得$n'=lceilfrac{n}{2} ceil$,直至$n=1$即为答案

    操作次数为$19lceillog_{2}n ceil+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被交换到较小处

    操作次数为$48lceilfrac{n+1}{2} ceil+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 }
    View Code
  • 相关阅读:
    MATLAB sort函数用法
    时频分析的一段代码注解
    离散时间信号的傅里叶变换
    两正弦加一噪声信号的频谱分析
    模拟信号的重建
    这10个让你笑的合不拢嘴的GitHub项目,居然拿了7万星
    最新大厂技术面试指南,GitHub10000星
    学习Python总是学了新内容又忘了旧的咋办?
    算法推荐,必读的6本经典神书。
    总计超5万星!GitHub上10个超级好玩的项目
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/15009233.html
Copyright © 2020-2023  润新知