#167. CRC

    ID: 167 Type: Default 1000ms 256MiB Tried: 0 Accepted: 0 Difficulty: (None) Uploaded By: Tags>2024暑假一期结训赛

CRC

Description

CRC是循环冗余校验(Cyclic Redundancy Check),是信息学中一个重要的检验数据传输是否出错的算法。

CRC算法的数学原理是多项式的模 22 除法(人话: 异或运算)。 img

图中每一步运算都是异或运算。
从图中可以看出,是否要进行异或操作,取决于数据中的这一位和之前对这一位异或后的值的异或值。

当然上面都只是在介绍CRC算法。
CRC算法可以简化为:

  1. 先将给出的除数 PP 的二进制形式最高位删去,得到简化后的除数 PP^\prime
  2. 设变量为 RR 为一个与 PP^\prime 的二进制位数相同的数,初始为 00
  3. 对原数据从高到低逐位进行处理,对于第 ii 次操作: 将原数据的第 ii 位与 RR 的最高位求异或,若结果为 11,则将 RR 左移一位并且与 PP^\prime 异或得到新的 RR,否则只将 RR 左移一位,注意左移时会舍弃最高位

现在,给你输入一个 简化后的 除数 PP^\prime 和一个数据流,请你计算出这个数据流对 PP^\prime 的CRC值。

Input Format

第一行输入两个正整数 nnkk,表示数据流中的 字节 数和 PP^\prime 的二进制位数。
第二行输入一个正整数 PP^\prime,表示 简化后的 除数。
第三行输入 nn 个空格隔开的非负整数 aia_i,表示数据流中按顺序每一字节的值。

Output Format

输出一个 kk 位二进制数,表示结果

1 4
11
229
0100
4 16
32773
248 127 0 170
0110010111011000

Hint

  1. 100%100\% 的数据,1k641 \le k \le 640n1060 \le n \le 10^6PP^\prime6464 位无符号整数范围内,0ai2550 \le a_i \le 255
  2. 你可以把输入的数据流看作是由原始数据每连续 88 位为一组分开并顺序排列得到的,即: 若原始数据等于 10010010110111111001001011011111,则输入的数据流为 146,223146, 223

样例解释

样例 #1

对上例,算法过程为

  1. PP^\prime 的二进制形式为 10111011
  2. RR 是一个 44 位的二进制数,初始值为 00,即 RR 的二进制形式为 00000000
  3. 循环计算异或步骤如下:
/*
原数据第1位为1,R=0000最高位为0
将R左移一位,得到R=0000
异或得1,将R与P'异或,得到R=1011

原数据第2位为1,R=1011最高位为1
将R左移一位,得到R=0110
异或得0,不做任何操作,得到R=0110

原数据第3位为1,R=0110最高位为0
将R左移一位,得到R=1100
异或得1,将R与P'异或,得到R=0111

原数据第4位为0,R=0111最高位为0
将R左移一位,得到R=1110
异或得0,不做任何操作,得到R=1110
.
.
.
原数据第8位为1,R=0010最高位为1
将R左移一位,得到R=0100
异或得0,不做任何操作,R=0100
*/
  1. 得到 R=0100R=0100