library

This documentation is automatically generated by online-judge-tools/verification-helper

View the Project on GitHub kk2a/library

:heavy_check_mark: convolution/convolution_and.hpp

Depends on

Verified with

Code

#ifndef KK2_CONVOLUTION_CONVOLUTION_AND_HPP
#define KK2_CONVOLUTION_CONVOLUTION_AND_HPP 1

#include <cassert>

#include "zeta_mobius_transfrom.hpp"

namespace kk2 {

template <class FPS> FPS convolution_and(FPS &a, const FPS &b) {
    assert(size(a) == size(b));
    int n = int(size(a)); // == int(size(b)
    if (!n) return {};
    assert((n & -n) == n);
    FPS c(b.begin(), b.end());

    superset_zeta_transform(a);
    superset_zeta_transform(c);
    for (int i = 0; i < n; i++) a[i] *= c[i];
    inverse_superset_zeta_transform(a);

    return a;
}

} // namespace kk2

#endif // KK2_CONVOLUTION_CONVOLUTION_AND_HPP
#line 1 "convolution/convolution_and.hpp"



#include <cassert>

#line 1 "convolution/zeta_mobius_transfrom.hpp"



#line 5 "convolution/zeta_mobius_transfrom.hpp"

namespace kk2 {

template <class FPS> void superset_zeta_transform(FPS &a) {
    int n = int(a.size());
    if (!n) return;
    assert((n & -n) == n);
    for (int i = 1; i < n; i <<= 1) {
        for (int j = 0; j < n; j++) {
            if ((i & j) == 0) a[j] += a[i ^ j];
        }
    }
}

template <class FPS> void inverse_superset_zeta_transform(FPS &a) {
    int n = int(a.size());
    if (!n) return;
    assert((n & -n) == n);
    for (int i = 1; i < n; i <<= 1) {
        for (int j = 0; j < n; j++) {
            if ((i & j) == 0) a[j] -= a[i ^ j];
        }
    }
}

template <class FPS> void subset_zeta_transform(FPS &a) {
    int n = int(a.size());
    if (!n) return;
    assert((n & -n) == n);
    for (int i = 1; i < n; i <<= 1) {
        for (int j = 0; j < n; j++) {
            if ((i & j) != 0) a[j] += a[i ^ j];
        }
    }
}

template <class FPS> void inverse_subset_zeta_transform(FPS &a) {
    int n = int(a.size());
    if (!n) return;
    assert((n & -n) == n);
    for (int i = 1; i < n; i <<= 1) {
        for (int j = 0; j < n; j++) {
            if ((i & j) != 0) a[j] -= a[i ^ j];
        }
    }
}

} // namespace kk2


#line 7 "convolution/convolution_and.hpp"

namespace kk2 {

template <class FPS> FPS convolution_and(FPS &a, const FPS &b) {
    assert(size(a) == size(b));
    int n = int(size(a)); // == int(size(b)
    if (!n) return {};
    assert((n & -n) == n);
    FPS c(b.begin(), b.end());

    superset_zeta_transform(a);
    superset_zeta_transform(c);
    for (int i = 0; i < n; i++) a[i] *= c[i];
    inverse_superset_zeta_transform(a);

    return a;
}

} // namespace kk2
Back to top page