2019.7.3 analog seven Lianzhu (determinant + k + random binary FWT)

Subject to the effect:


To a \ (n * n \) matrix for all permutations p, record \ (a [i] [p [i]] \) does not carry addition of the k-ary result, ask all numbers are ever recorded .

\(n<=50,p=2、3,0<=a[i][j]<p^7\)

answer:


Is arranged determinant may wish to consider:

\ (| A | = \ sum_ {p are arrayed} (- 1) ^ {p for the number of reverse} \ prod A [i] [p [i]] \)

Where A is a set of power series, × k is defined as binary convolutional not carry adder.

Suppose we do direct Gaussian elimination Determinant, we found that as \ ((-? 1) ^ \) power, could lead to the original ≠ 0 and add up to zero, so it is necessary coefficient as a random collection of power series coefficients.

With such a set of power series to the Gaussian elimination is clearly not lines, assuming p = 2, the FWT may wish, so that the convolution becomes a dot product, and does not affect the dot product between the different positions, it is possible to enumerate which one, then elimination.

In this case the complexity is \ (O (n-P ^ ^ *. 7. 3) \) .

The question then is how do FWT p hex.

Discover the essence of the FWT is to construct a reversible transition matrix, where the transfer matrix needs to meet to do it after the dot product is a k-ary not carry adder, which is circulating overflow k, then wish to direct units complex roots FFT to accomplish this thing .

I.e. transfer matrix \ (B [I] [J] = ij of W_k ^ {} \) , an inverse FWT is \ (W_k ^ {-} ij of / K \) .

\ (W_k \) may take the FFT \ ((COS (2 * \ PI / K), SiN (2 * \ PI / K) * I) \) , NTT may be taken as a \ (p | (mo- 1) \) primes mo, then \ (primitive root ^ {(mo-1) / k} \)

#include<bits/stdc++.h>
#define fo(i, x, y) for(int i = x, B = y; i <= B; i ++)
#define ff(i, x, y) for(int i = x, B = y; i <  B; i ++)
#define fd(i, x, y) for(int i = x, B = y; i >= B; i --)
#define ll long long
#define pp printf
#define hh pp("\n")
#define db long double
using namespace std;

int rand(int x, int y) {
    return ((ll) RAND_MAX * rand() + rand()) % (y - x + 1) + x;
}

const int mo = 1e9 + 9;

ll ksm(ll x, ll y) {
    ll s = 1;
    for(; y; y /= 2, x = x * x % mo)
        if(y & 1) s = s * x % mo;
    return s;
}

int num, n, k, a[51][51];
ll w[3];
void fwt(ll *a, int n, int f) {
    ll v = ksm(ksm(13, (mo - 1) / k), f == 1 ? 1 : mo - 2);
    w[0] = 1; ff(i, 1, k) w[i] = w[i - 1] * v % mo;
    for(int h = 1; h < n; h *= k) {
        for(int j = 0; j < n; j += k * h) {
            ff(i, 0, h) {
                ll c[3]; ff(u, 0, k) c[u] = 0;
                ff(u, 0, k) ff(v, 0, k) c[v] += a[i + j + h * u] * w[u * v % k] % mo;
                ff(u, 0, k) a[i + j + h * u] = c[u] % mo;
            }
        }
    }
    if(f == -1) {
        v = ksm(n, mo - 2);
        ff(i, 0, n) a[i] = a[i] * v % mo;
    }
}

const int N = 2187 + 5;

int m;
ll b[51][51][N], c[N], d[51][51];

ll solve(ll a[][51]) {
    ll s = 1;
    fo(i, 1, n) {
        int u = i;
        fo(j, i, n) if(a[j][i]) { u = j; break;}
        if(i != u) {
            fo(j, 1, n) swap(a[i][j], a[u][j]);
            s *= -1;
        }
        ll ni = ksm(a[i][i], mo - 2);
        fo(j, i + 1, n) if(a[j][i]) {
            ll v = -a[j][i] * ni % mo;
            fo(k, 1, n) a[j][k] = (a[j][k] + a[i][k] * v) % mo;
        }
    }
    fo(i, 1, n) s = s * a[i][i] % mo;
    return s;
}

int main() {
    srand(time (0) + clock());
    freopen("astrology.in", "r", stdin);
    freopen("astrology.out", "w", stdout);
    scanf("%d %d %d", &num, &n, &k);
    m = 1; fo(i, 1, 7) m = m * k;
    fo(i, 1, n) fo(j, 1, n) scanf("%d", &a[i][j]);
    fo(i, 1, n) fo(j, 1, n) {
        b[i][j][a[i][j]] = rand(1, mo - 1);
        fwt(b[i][j], m, 1);
    }
    solve(d);
    ff(u, 0, m) {
        fo(i, 1, n) fo(j, 1, n) d[i][j] = b[i][j][u];
        c[u] = solve(d);
    }
    fwt(c, m, -1);
    ff(i, 0, m) if(c[i]) pp("%d ", i);
}

Guess you like

Origin www.cnblogs.com/coldchair/p/11128753.html