1 条题解

  • 0
    @ 2025-8-24 23:07:44

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar andychen_2012
    **

    搬运于2025-08-24 23:07:44,当前版本为作者最后更新于2025-02-19 09:54:32,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    提交通道:IP over Avian Carrier - Problem - QOJ.ac

    我一开始的想法是,将连续 CC 个字符拼起来,变成一个 [0,2C)[0,2^C) 内的数,记 [0,2K)[0,2^K)popcount=C\mathrm{popcount}=C 的数构成的集合为 TT,而后设计一个函数 f(x):[0,2C)Tf(x):[0,2^C) \to T,使得该函数为双射关系。但是随后我发现只有 C=3,K=4C=3,K=4 的时候才可以设计出这样的函数。因此我不得不重新思考。

    我们首先将串 XX 按顺序拆分为 CC 个长为 NN 的串 a,b,c,a,b,c,\cdots

    C=3,K=4C=3,K=4 的时候,我们可以自然的想到四个串分别为 a,b,c,abca,b,c,a \oplus b \oplus c,解码是自然的。

    C=2,K=4C=2,K=4 的时候,我们考虑前三个分别是 a,b,aba,b,a \oplus b,对于第四个串,其需要能通过 aba \oplus b 解出 a,ba,b,因此可以考虑 si=aibixs_i=a_i \oplus b_i \oplus x,其中 xxai+ta_{i+t}bi+tb_{i+t},而由于其又需要能够通过 aabb 解码,那就应该是 ai+ta_{i+t}bi+tb_{i+t} 交替放置,我们可以使 t=1t=1,那么有奇数位 si=aibia(i+1)modns_i=a_i \oplus b_i \oplus a_{(i+1) \bmod n},偶数位 si=aibib(i+1)modns_i=a_i \oplus b_i \oplus b_{(i+1) \bmod n},反过来是一样的。解码时有两种情况:给出 aabbss,假设给定了 aa,此时考虑奇数位上 siaia(i+1)modn=bis_i \oplus a_i \oplus a_{(i+1) \bmod n}=b_i,求完奇数位的 bb 后,对于偶数位有 bi=siaib(i+1)modnb_i=s_i \oplus a_i \oplus b_{(i+1) \bmod n},因此 可以得到完整的 bb,对于给定 b,sb,s 同理。当给定 ab,sa \oplus b,s 时,我们可以得知偶数位的 aa 与奇数位的 bb,由 aba \oplus b 就可以得到偶数位的 bb 与奇数位的 aa。因此这种构造是可行的。

    C=3,K=5C=3,K=5 时,我们考虑设计 a,b,c,abca,b,c, a\oplus b \oplus c,但此时我们就需要另外一个同时设计 a,b,ca,b,c 的函数,有点困难。我们不妨设上面那种情况的 s=f(a,b)s=f(a,b),那么可以考虑 ac,bc,abc,c,f(a,b)a \oplus c,b \oplus c,a \oplus b \oplus c,c,f(a,b),这样无论选择哪三种,我们都可以解码出 a,b,ca,b,c

    核心代码如下,其中 ff 为编码,ggff 的解码。

    bitset<M> f(int N,bitset<M> x,bitset<M> y){
    	bitset<M> z;
    	z.reset();
    	for(int i=0;i<N;++i) z[i]=x[i]^y[i]^((i&1)?y[(i+1)%N]:x[(i+1)%N]);
    	return z;
    }
    string g(int N,bitset<M> A[6],bool vis[5]){
    	string code(2*N,'0');
    	if(vis[0]){
    		if(vis[2])
    			A[1]=A[0]^A[2];
    		if(vis[3]){
    			for(int i=0;i<N;i+=2) A[1][i]=(A[3][i]^A[0][i]^A[0][(i+1)%N]);
    			for(int i=1;i<N;i+=2) A[1][i]=(A[3][i]^A[0][i]^A[1][(i+1)%N]);
    		}
    	}
    	else if(vis[1]){
    		if(vis[2])
    			A[0]=A[1]^A[2];
    		if(vis[3]){
    			for(int i=1;i<N;i+=2) A[0][i]=(A[3][i]^A[1][i]^A[1][(i+1)%N]);
    			for(int i=0;i<N;i+=2) A[0][i]=(A[3][i]^A[1][i]^A[0][(i+1)%N]);
    		}
    	}
    	else if(vis[2]){
    		for(int i=0;i<N;++i) A[(i&1)][(i+1)%N]=A[2][i]^A[3][i];
    		for(int i=0;i<N;++i) A[((i&1)^1)][(i+1)%N]=A[2][(i+1)%N]^A[(i&1)][(i+1)%N];
    	}
    	for(int i=0;i<N;++i) code[i]=(char)A[0][i]+'0';
    	for(int i=0;i<N;++i) code[i+N]=(char)A[1][i]+'0';
    	return code;
    }
    string decode(int C, int K, int N, vector<string> Y, vector<int> I) {
    	bitset<M> A[6];
    	string code(C*N, '0');
    	for(int i=0;i<C;++i){
    		for(int j=i+1;j<C;++j){
    			if(I[i]>I[j]){
    				swap(I[i],I[j]);
    				swap(Y[i],Y[j]);
    			}
    		}
    	}
    	bool vis[5]={0};
    	for(int i=0;i<C;++i) vis[I[i]]=1;
    	#define setA for(int i=0;i<K;++i) A[i].reset();\
    	for(int j=0;j<C;++j) for(int i=0;i<N;++i) A[I[j]][i]=Y[j][i]-'0';
    	setA
    	if(C==3&&K==4){
    		if(I[2]==3){
    			bitset<M> s;
    			s=A[0]^A[1]^A[2]^A[3];
    			for(int i=0;i<3;++i){
    				if(vis[i]) continue;
    				A[i]=s;
    				break;
    			}
    		}
    		for(int i=0;i<3;++i){
    			for(int j=0;j<N;++j)
    				code[i*N+j]=(char)A[i][j]+'0';
    		}
    	}
    	else if(C==2&&K==4)
    		return g(N,A,vis);
    	else{
    		if(vis[4]){
    			bitset<M> s=A[4];
    			for(int i=0;i<3;++i){
    				if(vis[i]) A[i]^=s;
    			}
    			code.clear();
    			code=g(N,A,vis);
    			code+=Y[2];
    		}
    		else if(vis[3]){
    			if(vis[0]&&vis[1]) A[2]=A[0]^A[1];
    			else if(vis[0]&&vis[2]) A[1]=A[0]^A[2];
    			else if(vis[1]&&vis[2]) A[0]=A[1]^A[2];
    			for(int i=0;i<3;++i) vis[i]=!vis[i];
    			code.clear();
    			code=g(N,A,vis);
    			setA;
    			if(!vis[0]){
    				string y;
    				for(int i=0;i<N;++i) y.push_back((A[0][i]^(code[i]-'0'))+'0');
    				code+=y;
    			}
    			else if(!vis[1]){
    				string y;
    				for(int i=0;i<N;++i) y.push_back((A[1][i]^(code[i+N]-'0'))+'0');
    				code+=y;
    			}
    		}
    		else{
    			code.clear();
    			code+=change(N,A[1]^A[2]);
    			code+=change(N,A[0]^A[2]);
    			code+=change(N,A[0]^A[1]^A[2]);
    		}
    	}
    	return code;
    }
    
    • 1

    [NordicOI 2017] IP over Avian Carriers(通信题无法评测)

    信息

    ID
    11233
    时间
    2000ms
    内存
    1024MiB
    难度
    (无)
    标签
    递交数
    0
    已通过
    0
    上传者