Skip to content

Commit

Permalink
Merge branch 'yosupo06:master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
maspypy authored Oct 31, 2023
2 parents 248a4e0 + 76083b3 commit b87615c
Show file tree
Hide file tree
Showing 6 changed files with 221 additions and 26 deletions.
2 changes: 1 addition & 1 deletion graph/assignment/task.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ $N$
$a_{00}$ $a_{01}$ ... $a_{0,{N-1}}$
$a_{10}$ $a_{11}$ ... $a_{1,{N-1}}$
:
$a_{{N-1},0}$ $a_{{N-1},1}$ ... $a_{{N-1},{N-1}}$
$a_{ {N-1}, 0 }$ $a_{ {N-1}, 1 }$ ... $a_{ {N-1}, {N-1} }$
~~~

## @{keyword.output}
Expand Down
186 changes: 186 additions & 0 deletions math/exp_of_set_power_series/gen/overflow.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
// Reference : https://codeforces.com/blog/entry/92183

#include <algorithm>
#include <cassert>
#include <vector>

#include "../params.h"
#include "random.h"

namespace noshi91 {

namespace composition_egf_sps_internal {

template <class T, class F> void bitwise_transform(std::vector<T> &a, F f) {
const int n = a.size();
for (int w = 1; w < n; w *= 2) {
for (int i = 0; i < n; i += w * 2) {
for (int j = 0; j < w; j++) {
f(a[i + j], a[i + w + j]);
}
}
}
}

// f: sequence of length n + 1
// s: n variable set power series, constant term is 0
// output: \sum_{k=0}^{n} f_k s^k / k!
template <class T>
std::vector<T> composition_egf_sps(const std::vector<T> &f,
const std::vector<T> &s) {
const int n = int(f.size()) - 1;
assert(0 <= n && n <= 30);
assert(int(s.size()) == 1 << n);

std::vector<std::vector<std::vector<T>>> a(n + 1);
for (int i = 0; i <= n; i++) {
a[i].assign(i + 1, std::vector<T>(1 << i));
a[i][0][0] = f[n - i];
}

for (int v = 0; v < n; v++) {
std::vector h(v + 1, std::vector<T>(1 << v));
for (int i = 0; i < 1 << v; i++)
h[__builtin_popcount(i)][i] = s[(1 << v) + i];
for (int i = 0; i <= v; i++)
bitwise_transform(h[i], [](T &l, T &r) { r += l; });
for (int i = v + 1; i <= n; i++) {
for (int j = 0; j <= i; j++) {
std::copy_n(a[i][j].begin(), 1 << v, a[i][j].begin() + (1 << v));
}
}
for (int i = v; i < n; i++) {
for (int j = 0; j <= v; j++) {
for (int k = 0; j + k <= i; k++) {
for (int p = 0; p < 1 << v; p++) {
a[i + 1][j + k + 1][(1 << v) + p] += h[j][p] * a[i][k][p];
}
}
}
}
}

for (int i = 0; i <= n; i++)
bitwise_transform(a[n][i], [](T &l, T &r) { r -= l; });
std::vector<T> t(1 << n);
for (int i = 0; i < 1 << n; i++)
t[i] = a[n][__builtin_popcount(i)][i];
return t;
}

// f: polynomial
// s: set power series
// output: f(s)
template <class T>
std::vector<T> composition_poly_sps(std::vector<T> f, const std::vector<T> &s) {
assert(!s.empty());
const int n = __builtin_ctz(s.size());
assert(int(s.size()) == 1 << n);
std::vector<T> eval(n + 1, T(0));
const T c = s[0];
for (int i = 0; i <= n && !f.empty(); i++) {
T t = 0;
for (int j = f.size(); j-- > 0;)
t = t * c + f[j];
eval[i] = t;
for (int j = 1; j < int(f.size()); j++)
f[j - 1] = f[j] * j;
f.pop_back();
}
return composition_egf_sps(eval, s);
}

} // namespace composition_egf_sps_internal

using composition_egf_sps_internal::composition_egf_sps;
using composition_egf_sps_internal::composition_poly_sps;

} // namespace noshi91

#include <cstdio>

constexpr int mod = 998244353;
using ll = long long;
struct mm {
int x;
mm() : x(0) {}
mm(ll x_) : x(x_ % mod) {
if (x < 0)
x += mod;
}
mm &operator+=(mm b) {
if ((x += b.x) >= mod)
x -= mod;
return *this;
}
mm &operator-=(mm b) {
if ((x -= b.x) < 0)
x += mod;
return *this;
}
mm &operator*=(mm b) {
x = ll(x) * b.x % mod;
return *this;
}
mm &operator/=(mm b) { return *this *= b.pow(mod - 2); }
friend mm operator+(mm a, mm b) { return a += b; }
friend mm operator-(mm a, mm b) { return a -= b; }
friend mm operator*(mm a, mm b) { return a *= b; }
friend mm operator/(mm a, mm b) { return a /= b; }
mm pow(ll e) const {
mm r = 1, b = *this;
while (e) {
if (e & 1)
r *= b;
b *= b;
e >>= 1;
}
return r;
}
};

using mint = mm;

int popcnt(int x) { return __builtin_popcount(x); }

int main(int, char **argv) {

long long seed = atoll(argv[1]);
auto gen = Random(seed);

const int n = N_MAX;
std::vector<int> binom(n + 1);
binom[0] = 1;
binom[n] = 1;
for (int i = 1; i <= n - 1; ++i) {
binom[i] = binom[i - 1] * (n - i) / i;
}

std::vector<mint> a(1 << n);
for (int i = 0; i < (1 << n); ++i) {
int cnt = popcnt(i & ~(1 << (n - 1)));
int q = (MOD - 1) / binom[cnt];
a[i] = gen.uniform<int>(q / 100 * 99, q);
}

std::vector<mint> s{a.begin(), a.begin() + (1 << (n - 1))}, ln(n);
mint sign = 1;
for (int i = 1; i < n; ++i) {
ln[i] = sign / i;
sign = 0 - sign;
}

auto pre = noshi91::composition_egf_sps(ln, s);

for (int i = 0; i < (1 << (n - 1)); ++i) {
a[i] = pre[i];
}

printf("%d\n", n);
for (int i = 0; i < (1 << n); i++) {
printf("%d%c", a[i].x, " \n"[i + 1 == 1 << n]);
}

return 0;
}

2 changes: 2 additions & 0 deletions math/exp_of_set_power_series/hash.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
"n_01_00.out": "4355a46b19d348dc2f57c046f8ef63d4538ebb936000f3c9ee954a27460dd865",
"n_01_01.in": "eda407e4be0e446975a488667646ef3cbbf6a5b6fbec459a2a6142b6c232635c",
"n_01_01.out": "32ede1ac358dd8ee38d2157a560c4ca4f23a19ef3e431b8ccc479b2e24aea6c5",
"overflow_00.in": "ed7934e717aa489a7520ba89877a7861960f4c91f1658a9f5bc0af316dc006b6",
"overflow_00.out": "9b2bd77e9180b846f6b608e1440e3bfef1cf9b74bc6192263ee0aea99452e9f4",
"random_00.in": "fd363d616f80af7402396a912f3faad2f8b38c9cc8ff6d69ff0a643ac9339b73",
"random_00.out": "cff16ebca6bb37e81e5da7f3f8a9f8bfe0c0f2c5f032f59a6674675d1ef830b3",
"random_01.in": "b2d31191b8cb4657ea85b230f353f814e78001d893a06090a954ccf0fe5fca7a",
Expand Down
3 changes: 3 additions & 0 deletions math/exp_of_set_power_series/info.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ forum = "https://github.com/yosupo06/library-checker-problems/issues/974"
[[tests]]
name = "n_01.cpp"
number = 2
[[tests]]
name = "overflow.cpp"
number = 1

[[solutions]]
name = "naive.cpp"
Expand Down
48 changes: 24 additions & 24 deletions math/sharp_p_subset_sum/hash.json
Original file line number Diff line number Diff line change
@@ -1,50 +1,50 @@
{
"big_00.in": "50451a5a39a567ae3571029cefec8feef3a420a31ccecc787be33a834af0dd25",
"big_00.out": "aeb99f3da77d2f90a2e9c4dce50da327137ac5694dbf879c816640202ab4302c",
"big_00.out": "90bd5c21ee1b56fc4730a1e08fb9af45bd64de39ede666e73d980f2fa2626e61",
"big_01.in": "56e6ed0be42d9aca6b418e27db3f52dde6e88d2a3d681043e351dbcf42ed5747",
"big_01.out": "9fa38d7ea43ea5bd88985ae22beac72598f5cb31f0a21167079ca3a46549e979",
"big_01.out": "a1a73db290699e3fe7ed85d070ac14d1e511d900376c0b33a859e4851e486399",
"big_02.in": "681a6216423ccc496cc5fb7a7a75cec65b1df10d0a861253bcaa9af879fb9fc1",
"big_02.out": "c731db725da4c105caec527d9ccd53571998349ff64fde414ea4cdf6096ab2a9",
"big_02.out": "56dd9ad18748637f11050fa848a8345d38c09f9b63c92aebe5c7b59d950a79b4",
"big_03.in": "48ac9f3d78df0c537243e178939e5f442ab66e5e8b2264e7faf24edd31b63770",
"big_03.out": "09e9c2a701582fff00d8abd2adb5b2c0f5cc696e9881fbf9512c40f58f2107a5",
"big_03.out": "a2115fa348d31e0edf8c123f94e5dd54f203135794c6d2688940ff43f5593a3f",
"big_04.in": "2063a2a75064a73ecdf5b47f66f149968e8cba3982b619981fd00044033375be",
"big_04.out": "b6c1ed03effd299f2542f9729e00fc0a0149d435bf9ea09e3cc11f8b14442c3c",
"big_04.out": "b254d3bb8b9f6fd1692532285aedbb1315050c145b24488e0d7be8760ff5bb81",
"example_00.in": "14bf382e3740b284fbf7a77b6cbad9d3a4efd66b5441ee4187dd988f434056b9",
"example_00.out": "c6e2f1999b205966195183c6bcf6b87e5e44635a4fe3d242082d1f39a2b2920e",
"example_00.out": "c786d5cd70c1e9231d3f4a778f731eb0fd36fe0ff50f61c69056b33f3cc2910a",
"many_sets_00.in": "064860d6604a4f2a711bfb2b833e935ada2ddbef57b28b715e7dd0b3883862e5",
"many_sets_00.out": "0aac8ec48cbed3353bd09f0e13702b06b11624ab12ce62a94be5cfc741a13c9b",
"many_sets_00.out": "1f71d6bd360db413eb9589632ca040e9bca02008ae1c43d1fee9494a7090b8a4",
"many_sets_01.in": "e226f7ebab303fcdced6b367597d51d8524e49ee5d3a743f983e5d24e8922fd7",
"many_sets_01.out": "86290edf9135aa0f242967f4bfbe5dde6c40753efb71b5cb92a19deb40559831",
"many_sets_01.out": "53ade0fef6520e7024a62dc5502bf6283acc24940fd160bb38a658b0da9496a2",
"many_sets_02.in": "de0ebb9f40554476d0d9eebc3e6fc50c5ada01365628f8d33a3f1b2ca65655b1",
"many_sets_02.out": "9fa9e282c28e99e19fdd369e9944d799d088a66f5df2b7112a6523895f7d760f",
"many_sets_02.out": "8b01fb7e082e9a77dfb7fd2b535b78afc4634036c4140ddc03a8103b85190de8",
"many_sets_03.in": "49385ccb94227b1b510c9b68e8340c59e2b52b0ad1942c0f37ceb2a435a617a2",
"many_sets_03.out": "fade287eb7bb6fc6afe7f74302d1c7cf65bf9b4737af6b54687f793730ced438",
"many_sets_03.out": "5f899a0487d7a889f940052a5394d41a18e31f544adf96052c32f1c290091e8a",
"many_sets_04.in": "9eacb929bb249c7eefffbb3d10271db3e41e33e70503cc21d3ada94bf670744e",
"many_sets_04.out": "4f0e5c5ef3d261ae8f6195f47c5a05c1ea11acdc22fc21e4e06326737a98bb53",
"many_sets_04.out": "36755d3b0d0191e164215f3c918457b77fc7b10a410f9779b66d8955591795db",
"random_00.in": "8c2308fe7b2adc5c07ef4276f7d37263bb01aaa81b6cca3b870c9ed5ed445a3e",
"random_00.out": "78e016396f6caccacea1be685a222ae97723629039dc651f59c25df1259f4f2b",
"random_00.out": "e3f518327a7197be4f8f5097485334637087eebea0e24a51a3becb3ff4c25e85",
"random_01.in": "affce54ec7f05cd7f0e58de1d431a7bae5890550212136643b5e3f774f8bfb8a",
"random_01.out": "4b62d283c4e6b7f84205ce18213af22e00fa29dfa700a91a2c4558287a7d33cd",
"random_01.out": "697f083782218bc8b7dbd92931f884b72d04094739a8c0c80c9e6c6a8bb5c345",
"random_02.in": "f565cc402290128ef7a79f2c3b10dfe3b67896765a7b18c2bf672bc8c60b2166",
"random_02.out": "9ac2e5118a21cdd7b9ce858954c9f3a64062949020b5107607fbcd25e0d3e1da",
"random_02.out": "e2610db4d553acf684b94a07f8b6fb1a8c7c4d7fb964b95e6a5f97de7af8bcb7",
"random_03.in": "b6a130fab7eff8da039d815ce9df03a15de54d03eb0dbfa9f7c50dc4c4c8cc53",
"random_03.out": "03625ef1bc03ea313201f93d6e653e50e86a9d6e86c68d1bfdd65c833ac60c0f",
"random_03.out": "052325e33e591fbcbd0957b1df04459b1140eec9fa0fc43dff9d64989ef04d2e",
"random_04.in": "2f354dc76a61715b6299006f1ba15758a63efe9dad11c5f04386a830d32b8083",
"random_04.out": "0d1f38f7653dad53e49e2a1e9eb1a6404036f2d9cba010e6fd78a70588b3e4a9",
"random_04.out": "d84f376350505fda4cea28a7cc14470c18a75effe03cdd0d0747a3f31d89a745",
"small_00.in": "48421ad16ad0aec745f376b378ed07c13631f32e6606dbec76e332fa1314d352",
"small_00.out": "72b70e86767da81f9f5ec6da96657c3c7fc0b3b81a289e8095cc7c175a5d9615",
"small_00.out": "e7b27e0c999bcb06fdcf3c32a5a0d9d844423003b8075bb9354397152a7a6754",
"small_01.in": "6342d55b126c4c4a570c08491f7794e541261442782dc22cca72dbdde733fa77",
"small_01.out": "47963d30c17199b451b755c015c7a12b7d7b2eb35b89fba121134727f1845c42",
"small_01.out": "1684f5bf6166679f13e6b292b1fd9108e1142707721ff9f8546ba2f4f338743f",
"small_02.in": "b9f86b86337c450cb48d3c5019cba9c92308915c8d48ef4dd011355abee97426",
"small_02.out": "60d29c7c1011434822399d882e09f62590452b3ddcf7e86328825e056139f694",
"small_02.out": "e2c430654aae28ab43f3b6f9ced10548b913f959d2908fb640ff84a011fde8e4",
"small_03.in": "14932b02f5bf32318f44fddb93c0c9e3f9d48dda7c65a10331f3665d01346455",
"small_03.out": "6e471abacbe0bc38ecf84ae94a7d0950d698b5061679b7a6cd6d7fdbf53d80d0",
"small_03.out": "3b4e795c2a6cb86923a7f456c92ea5a023a3d86d007b513dfc29ed37e28c1f86",
"small_04.in": "f0744b7e10d21be515fbbc1353dc6dd15a7a3c16eb7fcf7fba9094da5c51c5fd",
"small_04.out": "29cf24941cd2ac99095799d31b8ef6e026cc4df6345b3f5d3829daea9df2e798",
"small_04.out": "7f7340989ed15271dd1cc548b78d1f379e4f1e5229d24b1426554485d8492c1e",
"small_N_large_T_00.in": "4d74d2e31476556c78c7839eb929f6a5f20287c5f99aca0aa6d75940c3bca59a",
"small_N_large_T_00.out": "6815be512ceb5568f609eeae2fcefb79c5defcb77cce2d92bedeaa3736ddfb51",
"small_N_large_T_00.out": "8aba7f57111639b97055915af4458753b795a88973824014aaad88d8878a9378",
"small_N_large_T_01.in": "d8187ef720a6336a96c0f4da2a48c8abfe25ee88c045c38ba5ed93366ba0eb34",
"small_N_large_T_01.out": "2ff9af9e0f155c87e2eabbf1cb47065a63bdfd996a74491feba142cbb86bb4b0",
"small_N_large_T_01.out": "6c742016c4e0530becf5d9c068965a49963e23d1aca9a1ff0d82c0bfc7019ccb",
"small_N_large_T_02.in": "8c5fe1489ff55d15158a696418e5adc088b4d284922b92b0140bef989ab878cb",
"small_N_large_T_02.out": "62ad6a9ce70c31ecdfb27207dd506b521a60fe4ecbebf1605f0aae6f8dfaf721"
"small_N_large_T_02.out": "3e5507adce2796e4b106ae680e558ebee8d36b77934ed707cb5d827edaa721b1"
}
6 changes: 5 additions & 1 deletion math/sharp_p_subset_sum/sol/correct.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,10 @@ int main(){
Mint add=fact.inv(j)*cnt[k];
if(j&1)f[k*j]+=add; else f[k*j]-=add;
} f=f.exp();
for(int i=1;i<=t;i++)printf("%d ",f[i].val);
for(int i=1;i<=t;i++) {
printf("%d",f[i].val);
if(i<t)printf(" ");
}
printf("\n");
return 0;
}

0 comments on commit b87615c

Please sign in to comment.