FWT 快速沃尔什变换

 

 



void fwt(ll *a, int op)
{
    for (int cnt_pre = 1, cnt_cur = 2; cnt_pre < tot; cnt_pre <<= 1, cnt_cur <<= 1)
        for (int i = 0; i < tot; i += cnt_cur)
            for (int j = 0; j < cnt_pre; j++)
            {
                if(op == 1) (a[i + j + cnt_pre] += a[i + j]) %= mod; //or
                else if(op == 2) (a[i + j] += a[i + j + cnt_pre]) %= mod; //and
                else if(op == 3) //xor
                {
                    ll k = a[i + j];
                    (a[i + j] += a[i + j + cnt_pre]) %= mod;
                    (a[i + j + cnt_pre] -= k - mod) %= mod;
                }
            }
}
void ufwt(ll *a, int op)
{
    for (int cnt_pre = tot >> 1, cnt_cur = tot; cnt_pre > 0; cnt_pre >>= 1, cnt_cur >>= 1)
        for (int i = 0; i < tot; i += cnt_cur)
            for (int j = 0; j < cnt_pre; j++)
            {
                if(op == 1) (a[i + j + cnt_pre] -= a[i + j] - mod) %= mod; //or
                else if(op == 2) (a[i + j] -= a[i + j + cnt_pre] - mod) %= mod; //and
                else if(op == 3)//xor
                {
                    ll k = a[i + j];
                    a[i + j] = (a[i + j] + a[i + j + cnt_pre]) * mod_inv_2 % mod;
                    a[i + j + cnt_pre] = (k - a[i + j + cnt_pre] + mod) * mod_inv_2 % mod;
                }
            }
}
void slove(ll *a,ll *b,int op)
{
    fwt(a,op);fwt(b,op);
    for (int j = 0; j < tot; j++)
            a[j] = a[j] * b[j] % mod;
    ufwt(a,op);//结果在a[i]中 
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值