Skip to content

Commit

Permalink
add
Browse files Browse the repository at this point in the history
  • Loading branch information
MtSaka committed Jul 14, 2024
1 parent 772485f commit 62ba832
Show file tree
Hide file tree
Showing 9 changed files with 189 additions and 28 deletions.
46 changes: 46 additions & 0 deletions ds/heap/double-ended-priority-queue.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#pragma once

#include "../../template/template.hpp"

template <typename T>
struct DoubleEndedPriorityQueue {
private:
priority_queue<T> pq1, rpq2;
priority_queue<T, vector<T>, greater<T>> pq2, rpq1;

public:
DoubleEndedPriorityQueue() {}
template <typename U>
DoubleEndedPriorityQueue(U first, U last) : pq1(first, last), pq2(first, last) {}
void push(const T& x) {
pq1.emplace(x);
pq2.emplace(x);
}
T get_max() {
while (!rpq2.empty() && pq1.top() == rpq2.top()) {
rpq2.pop();
pq1.pop();
}
return pq1.top();
}
T get_min() {
while (!rpq1.empty() && pq2.top() == rpq1.top()) {
rpq1.pop();
pq2.pop();
}
return pq2.top();
}
T pop_max() {
T res = get_max();
rpq1.emplace(res);
return pq1.pop(), res;
}
T pop_min() {
T res = get_min();
rpq2.emplace(res);
return pq2.pop(), res;
}
};
/**
* @brief Double-Ended Priority Queue
*/
34 changes: 34 additions & 0 deletions graph/others/enumerate-triangles.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#pragma once
#include "../graph-template.hpp"

template <typename T, typename F>
void enumerate_triangles(const Graph<T>& g, const F& f) {
// enumerate triangles
// O(Msqrt(N))
const int n = g.size();
vector<int> deg(n);
rep(i, n) deg[i] = g[i].size();
Graph<T> h(n);
rep(i, n) {
for (auto& e : g[i]) {
if (deg[i] < deg[e.to] || (deg[i] == deg[e.to] && i < e.to)) {
h.add_edge(i, e.to, true, e.cost);
}
}
}
vector<bool> table(n);
rep(i, n) {
for (auto& e : h[i]) table[e.to] = true;
for (auto& e1 : h[i]) {
const int j = e1.to;
for (auto& e2 : h[j]) {
const int k = e2.to;
if (table[k]) f(i, j, k);
}
}
for (auto& e : h[i]) table[e.to] = false;
}
}
/**
* @brief Enumerate Triangles
*/
4 changes: 2 additions & 2 deletions graph/tree/centroid.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

template <typename T = UnweightedEdge>
vector<int> centroid(const Graph<T>& g) {
cont int n = g.size();
const int n = g.size();
stack<pair<int, int>> s;
s.emplace(0, -1);
vector<int> sz(n), par(n);
Expand All @@ -27,7 +27,7 @@ vector<int> centroid(const Graph<T>& g) {
int val = n - sz[i];
for (auto& to : g[i])
if (to != par[i]) val = max(val, sz[to]);
if (val < siz) size = val, res.clear();
if (val < siz) siz = val, res.clear();
if (val == siz) res.emplace_back(i);
}
return res;
Expand Down
33 changes: 33 additions & 0 deletions math/convolution/large-convolution.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#pragma once

#include "convolution.hpp"
template <typename T, enable_if_t<is_modint<T>::value>* = nullptr>
vector<T> convolution_large(const vector<T>& a, const vector<T>& b) {
const int n = a.size(), m = b.size();
constexpr unsigned int p = T::get_mod();
if (n + m - 1 <= ((p - 1) & (1 - p))) return convolution(a, b);
constexpr int lg = ceil_log2((p - 1) & (1 - p)) - 1;
vector c(4, vector<T>(1 << (lg + 1)));
vector d(4, vector<T>(1 << (lg + 1)));
constexpr int mask = (1 << lg) - 1;
rep(i, n) c[i >> lg][i & mask] = a[i];
rep(i, m) d[i >> lg][i & mask] = b[i];
rep(i, 4) ntt(c[i]);
rep(i, 4) ntt(d[i]);
vector<T> ans(1 << (lg + 3));
rep(i, 7) {
vector<T> e(1 << (lg + 1));
rep(j, 4) {
const int k = i - j;
if (k < 0 || k >= 4) continue;
rep(l, 1 << (lg + 1)) e[l] += c[j][l] * d[k][l];
}
intt(e);
rep(j, 1 << (lg + 1)) ans[(i << lg) + j] += e[j];
}
ans.resize(n + m - 1);
return ans;
}
/**
* @brief Large Convolution
*/
25 changes: 25 additions & 0 deletions math/others/lagrange-interpolation.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#pragma once
#include "../../template/template.hpp"
#include "combinatorics.hpp"

template <typename T>
T lagrange_interpolation(const vector<T>& y, const long long& t) {
const int n = y.size() - 1;
Combinatorics<T> c(n);
if (t <= n) return y[t];
T ret;
vector<T> dp(n + 1, 1), pd(n + 1, 1);
for (int i = 0; i < n; i++) dp[i + 1] = dp[i] * T(t - i);
for (int i = n; i > 0; i--) pd[i - 1] = pd[i] * T(t - i);
for (int i = 0; i <= n; i++) {
T tmp = y[i] * dp[i] * pd[i] * c.finv(i) * c.finv(n - i);
if ((n - i) & 1)
ret -= tmp;
else
ret += tmp;
}
return ret;
}
/**
* @brief Lagrange Interpolation(ラグランジュ補間)
*/
26 changes: 0 additions & 26 deletions math/others/lagrange.hpp

This file was deleted.

10 changes: 10 additions & 0 deletions test/yosupo/convolution/convolution_mod_large.test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// competitive-verifier: PROBLEM https://judge.yosupo.jp/problem/convolution_mod_large
#include "../../../template/template.hpp"
#include "../../../math/convolution/large-convolution.hpp"
using mint = ModInt<998244353>;
int main() {
INT(n, m);
vector<mint> a(n), b(m);
sc >> a >> b;
print(convolution_large(a, b));
}
21 changes: 21 additions & 0 deletions test/yosupo/data_strucuture/double_ended_priority_queue.test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// competitive-verifier: PROBLEM https://judge.yosupo.jp/problem/double_ended_priority_queue
#include "../../../template/template.hpp"
#include "../../../ds/heap/double-ended-priority-queue.hpp"

int main() {
INT(n, q);
vector<int> s(n);
sc >> s;
DoubleEndedPriorityQueue<int> deq(all(s));
rep(q) {
INT(t);
if (t == 0) {
INT(x);
deq.push(x);
} else if (t == 1) {
print(deq.pop_min());
} else {
print(deq.pop_max());
}
}
}
18 changes: 18 additions & 0 deletions test/yosupo/graph/enumerate_triangles.test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// competitive-verifier: PROBLEM https://judge.yosupo.jp/problem/enumerate_triangles
#include "../../../template/template.hpp"
#include "../../../graph/others/enumerate-triangles.hpp"
#include "../../../math/modular/modint.hpp"
using mint = ModInt<998244353>;
int main() {
INT(n, m);
vector<mint> x(n);
sc >> x;
UnweightedGraph g(n);
g.read(m, 0);
mint ans = 0;
auto f = [&x, &ans](int i, int j, int k) {
ans += x[i] * x[j] * x[k];
};
enumerate_triangles(g, f);
print(ans);
}

0 comments on commit 62ba832

Please sign in to comment.