伝える - 随机 - 构造 - 线性基 - 通信

题目大意:
这是一道通信题。
A接受n,k个位置,和long long类型的x。返回一个长为n的字符串,满足那k个位置必须是’0’,其余可以是’0’或者’1’。B接受A返回的字符串,返回x。 n = 150 , k 40 , x 1 0 18 n=150,k\le40,x\le10^{18}
题解:
场上(去场上的路上)想到了一个做法,随机一个每个数值都是64位非负整数的常数列,然后A看x能用其中哪些数字异或得到(那k个位置对应的数字不能使用),将s的这些位置设为1.然后B根据s随便异或一下就可以了。这个过程相当于是用n-k>=110个数生成一个64位的满的线性基的概率,这个显然轻松满秩。
然而std还有一个构造解,考虑每三位视为一组。
若这一组中有至少两个位置被禁掉了,就不传输信息(000)。
否则若有一个位置被禁掉了,那么如果要传输的是1,那么s对应+=001或者110(取决于哪一个位置被禁掉了);否则如果要传输的是0,若第一位没有被禁掉,就s+=100。但是若第一位被禁掉了,那么用010和011分别表示00和01;最后三位都没被禁掉,用101和111表示10和11即可。

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define Rep(i,v) rep(i,0,(int)v.size()-1)
#define lint long long
#define ull unsigned lint
#define db long double
#define pb push_back
#define mp make_pair
#define fir first
#define sec second
#define debug(x) cerr<<#x<<"="<<x
#define sp <<" "
#define ln <<endl
#define N 200
#define M 64
using namespace std;
typedef pair<int,int> pii;
typedef set<int>::iterator sit;
struct RAND{
    ull x;RAND() { init(); } inline int init() { return x=998244353,0; }
    inline ull operator()() { return (x=(((x^1000000007)*998244353)+19260817)^(x<<13)^(x>>3)); }
};static RAND rnd;
namespace Alice_space{
    static ull val[N];
    struct LB{
        ull p[M+10],res[M+10];int pos[M+10];
        inline int init()
        {
            memset(p,0,sizeof p),
            memset(pos,0,sizeof pos),
            memset(res,0,sizeof res);
            return 0;
        }
        inline int ins(ull x,int ps)
        {
            ull r=0;
            for(int i=M-1;i>=0;i--)
                if((x>>i)&1)
                {
                    r^=res[i];
                    if(!p[i]) res[i]=r^(1ull<<i),p[i]=x,pos[i]=ps;
                    x^=p[i];
                }
            return 0;
        }
        inline string solve(ull x,int n)
        {
            string ans;ans.resize(n);
            rep(i,0,n-1) ans[i]='0';ull r=0;
            for(int i=M-1;i>=0;i--) if((x>>i)&1)
                assert(p[i]),x^=p[i],r^=res[i];
            assert(x==0);
            rep(i,0,M-1) if((r>>i)&1) ans[pos[i]]='1';
            return ans;
        }
    };static LB lb;static int ban[N];
    static string solve(int n,vector<int> p,ull x)
    {
        rnd.init(),lb.init();rep(i,0,n-1) ban[i]=0;
        Rep(i,p) ban[p[i]]=1;rep(i,0,n-1) val[i]=rnd();
        rep(i,0,n-1) if(!ban[i]) lb.ins(val[i],i);
        return lb.solve(x,n);
    }
}
string alice(int n,const vector<int> &p,lint x)
{
    return Alice_space::solve(n,p,x);
}
namespace Bob_space{
    static ull val[N];
    inline lint solve(string s)
    {
        int n=(int)s.length();ull ans=0;
        rnd.init();rep(i,0,n-1) val[i]=rnd();
        rep(i,0,n-1) if(s[i]=='1') ans^=val[i];
        return (lint)ans;
    }
}
lint bob(const string &s)
{
    return Bob_space::solve(s);
}

猜你喜欢

转载自blog.csdn.net/Mys_C_K/article/details/88534784