1 条题解

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

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar Rainbow_qwq
    **

    搬运于2025-08-24 23:05:07,当前版本为作者最后更新于2024-10-15 15:21:12,作者可能在搬运后再次修改,您可在原文处查看最新版

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

    以下是正文


    假设有 2n2n 位,考虑把每个数分成前 nn 位和后 nn 位。

    先构造一个 2n2^n 元有乘法、加法的有限域,这个可以通过找一个不可约多项式构造,见 P3923

    然后对于 x=[0,2n1]x=[0,2^n-1],前 nn 位填 xx,后 nn 位填 x3x^3 在有限域运算下的值,构造出一个 2n2n 位的数。

    这样如果两个 pair (a,b),(c,d)(a,b),(c,d) 的 xor 相等,就需要满足 a+b=c+da+b=c+d a3+b3=c3+d3a^3+b^3=c^3+d^3

    由于在该 2n2^n 有限域下加法等同与 xor,可以推出 a3+b3=c3+d3ab(a+b)=cd(c+d)ab=cda^3+b^3=c^3+d^3 \to ab(a+b) = cd(c+d) \to ab=cd

    由于同时有 ab=cdab=cda+b=c+da+b=c+d,则 {a,b}\{a,b\}{c,d}\{c,d\} 都是方程 x2(a+b)x+abx^2-(a+b)x+ab 的解,而这个方程只有至多两个解,也就说明 {a,b}={c,d}\{a,b\} = \{c,d\}

    那么这样构造就不会有两个不同的 pair 的 xor 相同,并且构造了 2n2^n 个数。

    // what is matter? never mind.
    #include<bits/stdc++.h>
    #define For(i,a,b) for(int i=(a);i<=(b);++i)
    #define Rep(i,a,b) for(int i=(a);i>=(b);--i)
    //#define int long long
    using namespace std;
    
    int mod;
    
    #define fi first
    #define se second
    #define pb push_back
    #define mkp make_pair
    typedef pair<int,int>pii;
    typedef vector<int>vi;
    
    #define maxn 55
    #define inf 0x3f3f3f3f
    #define poly vector<modint>
    
    int n,p,k;
    
    poly operator +(poly a,poly b){
    	int n=max(a.size(),b.size());a.resize(n),b.resize(n);
    	For(i,0,n-1)a[i]+=b[i];return a;
    }
    poly operator -(poly a,poly b){
    	int n=max(a.size(),b.size());a.resize(n),b.resize(n);
    	For(i,0,n-1)a[i]-=b[i];return a;
    }
    poly operator *(poly a,modint b){
    	int n=a.size();
    	For(i,0,n-1)a[i]*=b;return a;
    } 
    poly operator *(poly a,poly b){
    	if(!a.size()||!b.size())return {};
    	poly c(a.size()+b.size()-1,0);
    	for(int i=0;i<a.size();++i)
    		for(int j=0;j<b.size();++j)
    			c[i+j]+=a[i]*b[j];
    	return c;
    }
    
    poly operator %(poly a,poly b){
    	while(b.back().x==0)b.pop_back();
    	while(1){
    		while(a.size()&&a.back().x==0)a.pop_back();
    		if(a.size()<b.size())return a;
    		int t=a.size()-b.size();
    		modint w=a.back()/b.back();
    		For(i,0,(int)b.size()-1)a[i+t]-=b[i]*w;
    		assert(a.back().x==0);
    	}
    }
    
    void init(poly &a,int x){
    	if(a.size()<k)a.resize(k);
    	For(i,0,k-1)a[i]=x%p,x/=p;
    }
    int get(poly a){
    	if(a.size()<k)a.resize(k);
    	int res=0;
    	Rep(i,k-1,0)res=res*p+a[i].x;
    	return res;
    }
    
    bool chk(poly a){
    	poly b;
    	For(i,p,n-1){
    		init(b,i);
    		poly c=a%b;
    		if(!c.size())return 0;
    	}
    	return 1;
    }
    
    poly qwq(){
    	poly a(k+1); a[k]=1;
    	For(i,1,n-1){
    		init(a,i);
    		if(chk(a))return a;
    	}
    	assert(0);
    }
    
    int pri[maxn],pc[maxn],tot;
    void fj(int n){
    	For(i,2,n)
    		if(n%i==0){
    			pri[++tot]=i;
    			while(n%i==0)n/=i,++pc[tot];
    		}
    }
    
    signed main()
    {
    	n=1<<read();
    	k=0;
    	while((1<<(k*2))<n)k++;
    	n=(1<<k);
    	mod=p=2;
    	poly a;
    	a=qwq();//puts("QWQWQ");
    //	for(auto x:a)cout<<x.x<<' ';puts(" A");
    	vi o;
    	int s=(1<<k);
    	For(i,0,(1<<k)-1){
    		poly x; init(x,i);
    		poly y=x*x%a*x%a;
    		int out=get(y);
    		out|=(i<<k);
    		o.pb(out);
    	}
    	cout<<o.size()<<"\n";
    	for(int x:o)cout<<x<<" \n"[x==o.back()];
    	return 0;
    }
    // (1 0 1) % 
    
    • 1

    信息

    ID
    10657
    时间
    10000ms
    内存
    2048MiB
    难度
    7
    标签
    递交数
    0
    已通过
    0
    上传者