线性基

https://www.luogu.com.cn/problem/solution/P3812
洛谷讲解链接

点击查看代码
int cnt;//记录线性基个数,数集确定,cnt确定
inline void ins(ll x)
{
    f_(i,62,0)
    {
        if(x&(1ll<<i))
        {
            if(!p[i])
            {
                p[i]=x;break;
            }
            x^=p[i];//保证线性基如果能插入一定是可以被原有数异或出来
            //的
        }
    }
}
inline int ask_exist(ll x)//判断x能否被已有数集表示出来
{
    f_(i,62,0)
    {
        if(x&(1ll<<i))
        {
            if(!p[i])return 0;//插入成功代表不能被表示
            x^=p[i];
        }
    }
    /*这是另一个版本,一样的。
    因为假设p[i]==0而且x有这一位,这一位一定会被保留下来从而x不是0,代表
    x不能被表示
    f_(i,62,0)
    if(x&(1ll<<i))x^=p[i];
    return x==0;
    */
    return 1;
}
inline ll ask_max()//查询子集异或最大值
{
    ll ans=0;
    f_(i,62,0)
    if((ans^p[i])>ans)ans^=p[i];//因为高位贪心不影响低位
    return ans;
}
inline ll ask_min()//查询子集异或最小值
{
    if(zero)return 0;//因为线性基不能表示出0:
    //假设pi^pj^pk==0,那么pi^pj=pk,但是i/j/k的最高位不一致,也就是说
    //对于最高位的1假设在i,那么pk的第i位的1消除不掉,但是Pk显然第
    //i位没有1,所以矛盾
    _f(i,0,62)if(p[i])return p[i];
}
/
inline void rebuild_of_ask_Kth_min()
{
    //rebuild:
    cnt=0,top=0;
    f_(i,MB,0)//必须从高位到低位!
    //可以理解成pj要求原始数组
    {
        f_(j,i-1,0)
        if(p[i]&(1ll<<j))p[i]^=p[j];
    }
    _f(i,0,MB)if(p[i])d[cnt++]=p[i];//新的线性基
}
inline ll ask_Kth_min(int k)//排除了0的异或子集第k小
{
    if(k>=(1ll<<cnt))return -1;//取等号,因为
    //cnt代表可以不同的位数,本来应该是有2^cnt种构造数的方案
    //但是对于每一位都是0的我已经提前考虑过了,所以当k=2^cnt其实是
    //不存在的
    ll ans=0;
    _f(i,0,cnt-1)//对于排名的累加
    if(k&(1ll<<i))ans^=d[i];//二进制分解
    return ans;
}
inline ll ask_rank(ll x)//查询x在所有数集异或可以表示出来的集合中
//的排名
{
    int ans=0;
    f_(i,cnt-1,0)if(x>=d[i])ans+=(1ll<<i),x^=d[i];//只考虑
    //每一个重建线性基是1的位,x满不满足条件
    //其实就是比较对于可表示集合中,如果第i个有意义位是0,更高位
    //已经进行完决策(如果x更大,就有2种,x小,就只能让高某位是0)
    //对于低位任意的一个排名累加
    //如果x>d[i],说明i位0/1都行,否则0一定行,1不行
    return ans+zero;
}
int main()
{
    chu("%lld",tmp-zero ? ask_Kth_min(tmp-zero):0ll);
}
/

附加百度上搜不到的一个结论:一组数可以表示出来的数个数就是线性基的每一位!=0的个数的2次幂,\(2^{cnt}\):解释:因为线性基中每个数都不能互相异或出来,所以对于每个基选或者不选都会组合出不同的数。

线性基求最大^路径和

(1)起点1终点n

考虑答案组成部分:一条从起点到终点的链+若干个环,把图中所有环的线性基搞出来,任意链扔基里求max。

(2)起点1终点1

若干环

posted on 2022-10-07 17:47  HZOI-曹蓉  阅读(10)  评论(0编辑  收藏  举报