[硫化铂]密码

Posted StaroForgin

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[硫化铂]密码相关的知识,希望对你有一定的参考价值。

密码

题解

完了,居然开始阴间的密码题了。

首先的第一个想法是像 D N A DNA DNA片段一样,加几个开始码,结束码用于识别。但显然,这最多只能拿前面的 55 p t s 55pts 55pts,我们的正解最多只给我们 50 50 50个空位,显然是不行的。
这个时候,我们就可以联想到我们传统的线性变换方法用于加密了,由于我们给定的是加密串中的 k k k个位置与整个原文串,我们得用加密串的剩下 m − k m-k mk个位置凑出整个原串。
通过不连续的 m − k m-k mk个位置凑出原串,我们不妨就给它随机 m − k m-k mk个长度为 n n n 0 / 1 0/1 0/1串,只要这个 0 / 1 0/1 0/1串是满秩的,那么它们是一定能够异或出我们的原串的。
实际上,由于 m − k ⩾ n + 50 m-k\\geqslant n+50 mkn+50,所以它们满秩的概率是相当高的。
我们可以就让我们解密串上的第 i i i位表示我们凑出原串的过程是否需要异或上我们的第 i i i个串,这可以用线性基就可以算出。
当然,由于我们解密的时候并不知道哪几位是开始就固定的,所以我们开始固定的 k k k位当然也有自己固定的 0 / 1 0/1 0/1串,只是它们异不异或上的状态是固定的,所以说,相当于他最开始就已经对原串做了 k k k个线性变换,我们解密时是知道这 k k k个线性变换状况的,一并去掉就行了。
当然,上面的方法当然需要我们加密与解密时每一位对应的 0 / 1 0/1 0/1串是相同的,事实上。用相同的种子生成这个 0 / 1 0/1 0/1就行了。

时间复杂度 O ( n 2 m ω ) O\\left(\\fracn^2m\\omega\\right) O(ωn2m)

源码

#include "password.h"
#include<bits/stdc++.h>
using namespace std;
#define MAXN 2055
#define lowbit(x) (x&-x)
#define reg register
#define pb push_back
#define mkpr make_pair
#define fir first
#define sec second
#define lson (rt<<1)
#define rson (rt<<1|1)
typedef long long LL;
typedef unsigned long long uLL; 
typedef long double ld;
typedef pair<int,int> pii;
template<typename _T>
_T Fabs(_T x)return x<0?-x:x;
template<typename _T>
void read(_T &x)
	_T f=1;x=0;char s=getchar();
	while(s>'9'||s<'0')if(s=='-')f=-1;s=getchar();
	while('0'<=s&&s<='9')x=(x<<3)+(x<<1)+(s^48);s=getchar();
	x*=f;

template<typename _T>
void print(_T x)if(x<0)x=(~x)+1;putchar('-');if(x>9)print(x/10);putchar(x%10+'0');
int gcd(int a,int b)return !b?a:gcd(b,a%b);
int add(int x,int y,int p)return x+y<p?x+y:x+y-p;
void Add(int &x,int y,int p)x=add(x,y,p);
int qkpow(int a,int s,int p)int t=1;while(s)if(s&1)t=1ll*t*a%p;a=1ll*a*a%p;s>>=1;return t;
bitset<1005>val[MAXN],aim,mat[MAXN],tmp;
bitset<MAXN>ip[MAXN],dmp,answer;
void insert(int n,int id)
	tmp=val[id];dmp.reset();dmp[id]=1;
	for(int i=0;i<n;i++)if(tmp.test(i))
		if(mat[i].test(i))tmp^=mat[i],dmp^=ip[i];
		elsemat[i]=tmp;ip[i]=dmp;break;
	

void encoder(int n,int m,int k,const char* a,const char* b,char* ans)
	mt19937 e(114514);uniform_int_distribution<int> g(0,1);
	for(int i=0;i<m;i++)for(int j=0;j<n;j++)val[i][j]=g(e);
	for(int i=0;i<n;i++)aim[i]=a[i]-'0';
	for(int i=0;i<m;i++)if(b[i]=='1')aim^=val[i];
	for(int i=0;i<m;i++)if(b[i]=='?')insert(n,i);
	for(int i=0;i<n;i++)if(aim.test(i))aim^=mat[i],answer^=ip[i];
	for(int i=0;i<m;i++)if(b[i]=='?')ans[i]=answer[i]+'0';else ans[i]=b[i];

void decoder(int n,int m,const char *a,char* ans)
	mt19937 e(114514);uniform_int_distribution<int> g(0,1);
	for(int i=0;i<m;i++)for(int j=0;j<n;j++)val[i][j]=g(e);aim.reset();
	for(int i=0;i<m;i++)if(a[i]=='1')aim^=val[i];
	for(int i=0;i<n;i++)ans[i]=aim[i]+'0';

谢谢!!!

以上是关于[硫化铂]密码的主要内容,如果未能解决你的问题,请参考以下文章

[硫化铂]传染

[硫化铂]treecnt

[硫化铂]启程的日子

[硫化铂]卿且去

[硫化铂]好

[硫化铂]未来