我好咸啊,一个多小时才写完这sb题
给一个长2e5的16进制原串(要转成2进制)
要解密这个串
首先要判断是否合法,把原串分成9位一段(最后不够9个的不要了),对于每段 统计前8位1的个数 第9位是校验码,1的个数是偶数 第9位是1 或者1的个数是奇数 第九位是0 都是合法的 否则不合法
然后把合法的串拼起来
给出一些(<=256)解密规则 形如 x(十进制) y(二进制) 代表y解密后是x 保证任何一个y不会是其他的y的前缀
要求输出解密后的串
#include <bits/stdc++.h>
using namespace std;
char s[MAXN*4], s2[MAXN*4], tmp[15];
int Len, n, len, x, top, Case, top1;
struct bittrie {
int t[MAXN*4][2], cnt;
int isword[MAXN*4];
inline void init() {
mset(t, 0), mset(isword, 0); cnt = 0;
}
inline void insert(int cur, char *p) {
int u = 0;
while (*p) {
int v = *p++ - '0';
int &x = t[u][v];
u = x ? x : x = ++cnt;
}
isword[u] = cur;
}
inline int query(char *p) {
int u = 0, tt = 0;
while (*p) {
int v = *p++ - '0';
u = t[u][v];
++tt;
if (isword[u]) return putchar(isword[u]), tt;
}
}
}T;
int main() {
in, Case;
while(Case--) {
T.init();
in, Len, n;
top1 = top = 0;
lop(i,1,n) {
in, x, tmp;
T.insert(x, tmp);
}
in, s+1;
for(int i = 1; s[i]; ++i) {
int tt;
if (islower(s[i])) s[i] -= 32;
if (isdigit(s[i])) tt = s[i] - '0';
else tt = s[i] - 'A' + 10;
for(int j = 3; j >= 0; --j) s2[++top] = ((tt & (1 << j)) != 0) + '0';
s[i] = 0;
}
top = (top / 9) * 9;
assert(top%9==0);
for(int i = 1; i <= top; i += 9) {
int cnt = 0;
for(int j = i; j <= i + 7; ++j) if (s2[j] == '1') ++cnt;
if ((cnt & 1) != s2[i+8] - '0')
for(int j = i; j <= i + 7; ++j) s[++top1] = s2[j];
}
s[top1+1] = ' ';
int cur = 1, tt = 0;
while (cur <= top1) {
cur += T.query(s+cur);
if (++tt == Len) break;
}
puts("");
}
return 0;
}