제출 #1329087

#제출 시각아이디문제언어결과실행 시간메모리
1329087SmuggingSpunBit Shift Registers (IOI21_registers)C++20
100 / 100
2 ms764 KiB
#include "registers.h"
#include<bits/stdc++.h>
using namespace std;
namespace sub1{
  const int m = 100;
  const int b = 2000;
  void solve(int s, int n, int k){
    if(k == 1){
      append_right(1, 0, 1);
      append_left(0, 0, b - 1);
      append_right(0, 0, b - 1);
      append_and(0, 0, 1);
      return;
    }
    auto get_bit = [&] (int t, int x, int i){
      append_left(t, x, b - i - 1);
      append_right(t, t, b - 1);
    };
    get_bit(3, 0, 0);
    get_bit(1, 0, 1);
    get_bit(4, 0, 2);
    append_right(2, 0, 3);
    append_xor(5, 1, 2);
    append_not(5, 5);
    append_not(6, 2);
    append_and(6, 1, 6);
    append_not(7, 4);
    append_and(7, 3, 7);
    append_and(7, 5, 7);
    append_or(6, 7, 6);
    append_and(2, 2, 6);
    append_and(4, 4, 6);
    append_not(6, 6);
    append_and(1, 1, 6);
    append_and(3, 3, 6);
    append_left(0, 1, 1);
    append_left(2, 2, 1);
    append_add(0, 0, 2);
    append_add(0, 0, 3);
    append_add(0, 0, 4);
  }
}
namespace sub2{
  const int m = 100;
  const int b = 2000;
  void solve(int s, int n, int k){
    if(k == 1){
      append_right(1, 0, 1);
      append_left(0, 0, b - 1);
      append_right(0, 0, b - 1);
      append_and(0, 0, 1);
      return;
    }
    auto get_bit = [&] (int t, int x, int i){
      append_left(t, x, b - i - 1);
      append_right(t, t, b - 1);
    };
    get_bit(1, 0, 0);
    get_bit(2, 0, 1);
    get_bit(3, 0, 2);
    append_right(4, 0, 3);
    append_and(5, 2, 4);
    append_xor(2, 5, 2);
    append_or(1, 1, 2);
    append_xor(4, 5, 4);
    append_or(3, 3, 4);
    append_and(0, 1, 3);
    append_left(5, 5, 1);
    append_add(0, 0, 5);
  }
}
namespace sub3{
  const int m = 100;
  const int b = 2000;
  void solve(int s, int n, int k){
    auto copy_number = [&] (int t, int i){
      append_left(t, 0, b - (i + 1) * k);
      append_right(t, t, b - k);
    };
    copy_number(1, 0);
    for(int i = 1; i < n; i++){
      copy_number(2, i);
      append_not(3, 2);
      append_add(3, 3, 1);
      append_right(3, 3, b - 1);
      append_left(4, 3, 1);
      append_or(3, 3, 4);
      append_left(4, 3, 2);
      append_or(3, 3, 4);
      append_left(4, 3, 4);
      append_or(3, 3, 4);
      append_left(4, 3, 8);
      append_or(3, 3, 4);
      append_and(1, 1, 3);
      append_not(3, 3);
      append_and(2, 2, 3);
      append_or(1, 1, 2);
    }
    append_move(0, 1);
  }
}
namespace sub4{
  const int m = 100;
  const int b = 2000;
  void solve(int s, int n, int k){
    vector<bool>t(b, false);
    for(int i = 0; i < n; i++){
      t[(i + 1) * k] = true;
    }
    append_store(3, t);
    while(n > 1){
      int cnt = (n + 1) >> 1;
      fill(t.begin(), t.end(), false);
      fill(t.begin(), t.begin() + cnt * k, true);
      append_store(1, t);
      append_and(1, 1, 0);
      append_right(0, 0, (n - cnt) * k);
      append_xor(5, 0, 1);
      append_not(4, 1);
      append_add(2, 0, 4);
      append_xor(2, 2, 5);
      append_and(2, 2, 3);
      append_right(2, 2, 1);
      for(int len = 1; len < k; len <<= 1){
        append_right(4, 2, min(len, k - len));
        append_or(2, 2, 4);
      }
      append_and(0, 0, 2);
      append_not(2, 2);
      append_and(1, 1, 2);
      append_or(0, 0, 1);
      n = cnt;
    }
  }
}
namespace sub5{
  const int m = 100;
  const int b = 2000;
  void solve(int s, int n, int k){
    auto copy_number = [&] (int t, int i){
      append_left(t, 0, b - (i + 1) * k);
      append_right(t, t, b - k);
    };
    for(int _ = 1; _ < n; _++){
      for(int i = 1; i < n; i++){
        copy_number(1, i - 1);
        copy_number(2, i);
        append_not(3, 2);
        append_add(4, 3, 1);
        append_right(4, 4, b - 1);
        append_left(5, 4, 1);
        append_or(4, 4, 5);
        append_left(5, 4, 2);
        append_or(4, 4, 5);
        append_left(5, 4, 4);
        append_or(4, 4, 5);
        append_left(5, 4, 8);
        append_or(4, 4, 5);
        append_and(6, 2, 4);
        append_not(4, 4);
        append_and(7, 1, 4);
        append_or(6, 6, 7);
        append_xor(2, 2, 1);
        append_xor(2, 2, 6);
        append_move(1, 6);
        vector<bool>t(b, true);
        fill(t.begin() + (i - 1) * k, t.begin() + (i + 1) * k, false);
        append_store(6, t);
        append_and(0, 0, 6);
        append_left(1, 1, i * k);
        append_left(2, 2, (i - 1) * k);
        append_or(0, 0, 1);
        append_or(0, 0, 2);
      }
    }
  }
}
namespace sub6{
  const int m = 100;
  const int b = 2000;
  void solve(int s, int n, int k){
    vector<bool>t(b, false);
    for(int i = 0; i < n; i++){
      t[(i + 1) * k] = true;
    }
    append_store(3, t);
    fill(t.begin(), t.end(), false);
    for(int i = 0; i + 1 < n; i += 2){
      for(int j = 0; j < k; j++){
        t[i * k + j] = true;
      }
    }
    append_store(10, t);
    fill(t.begin(), t.end(), false);
    for(int i = 1; i + 1 < n; i += 2){
      for(int j = 0; j < k; j++){
        t[i * k + j] = true;
      }
    }
    append_store(11, t);
    for(int _ = (n >> 1) + 1; _ > 0; _--){
      for(int p = 0; p < 2; p++){
        append_right(1, 0, k);
        append_xor(5, 0, 1);
        append_not(4, 1);
        append_add(2, 0, 4);
        append_xor(2, 2, 5);
        append_and(2, 2, 3);
        append_right(2, 2, 1);
        for(int len = 1; len < k; len <<= 1){
          append_right(4, 2, min(len, k - len));
          append_or(2, 2, 4);
        }
        append_and(5, 0, 2);
        append_not(2, 2);
        append_and(6, 1, 2);
        append_or(5, 5, 6);
        append_and(5, 5, 10 + p);
        append_move(6, 5);
        append_xor(6, 6, 0);
        append_xor(6, 6, 1);
        append_and(6, 6, 10 + p);
        append_left(6, 6, k);
        append_or(5, 5, 6);
        if(p == 0){
          if(n & 1){
            append_right(6, 0, (n - 1) * k);
            append_left(6, 6, (n - 1) * k);
            append_or(5, 5, 6);
          }
        }
        else{
          append_left(6, 0, b - k);
          append_right(6, 6, b - k);
          append_or(5, 5, 6);
          if(~n & 1){
            append_right(6, 0, (n - 1) * k);
            append_left(6, 6, (n - 1) * k);
            append_or(5, 5, 6);
          }
        }
        append_move(0, 5);
      }
    }
  }
}
void construct_instructions(int s, int n, int k, int q){
  if(s == 0){
    if(n == 2 && k <= 2){
      if(q == 1000){
        return sub1::solve(s, n, k);
      }
      return sub2::solve(s, n, k);
    }
    if(q == 4000){
      return sub3::solve(s, n, k);
    }
    return sub4::solve(s, n, k);
  }
  if(n <= 10 && q == 4000){
    return sub5::solve(s, n, k);
  }
  return sub6::solve(s, n, k);
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...