Skip to content

Commit

Permalink
Merge pull request #1214 from Misuki743/master
Browse files Browse the repository at this point in the history
add problem: unionfind with potential
  • Loading branch information
maspypy authored Jul 27, 2024
2 parents 8f541db + 3d1c863 commit 3753a29
Show file tree
Hide file tree
Showing 12 changed files with 1,144 additions and 0 deletions.
63 changes: 63 additions & 0 deletions datastructure/unionfind_with_potential/checker.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// https://github.com/MikeMirzayanov/testlib/blob/master/checkers/wcmp.cpp

// The MIT License (MIT)

// Copyright (c) 2015 Mike Mirzayanov

// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:

// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

#include "testlib.h"

using namespace std;

int main(int argc, char * argv[])
{
setName("compare sequences of tokens");
registerTestlibCmd(argc, argv);

int n = 0;
string j, p;

while (!ans.seekEof() && !ouf.seekEof())
{
n++;

ans.readWordTo(j);
ouf.readWordTo(p);

if (j != p)
quitf(_wa, "%d%s words differ - expected: '%s', found: '%s'", n, englishEnding(n).c_str(), compress(j).c_str(), compress(p).c_str());
}

if (ans.seekEof() && ouf.seekEof())
{
if (n == 1)
quitf(_ok, "\"%s\"", compress(j).c_str());
else
quitf(_ok, "%d tokens", n);
}
else
{
if (ans.seekEof())
quitf(_wa, "Participant output contains extra tokens");
else
quitf(_wa, "Unexpected EOF in the participants output");
}
}

11 changes: 11 additions & 0 deletions datastructure/unionfind_with_potential/gen/example_00.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
4 10
0 1 0 9
1 0 2
0 2 1 90
0 2 0 99
0 0 2 123
0 3 1 990
1 0 2
1 2 0
1 3 0
1 1 1
44 changes: 44 additions & 0 deletions datastructure/unionfind_with_potential/gen/max_random.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#include <iostream>
#include "random.h"
#include "../sol/acl.h"
#include "../params.h"

using namespace std;
using namespace atcoder;

using mint = modint998244353;

mint id() { return 0; }
mint op(const mint &a, const mint &b) { return a + b; }
mint inv(const mint &a) { return -a; }

int main(int, char* argv[]) {

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

int n = gen.uniform<int>(1, N_MAX);
int q = Q_MAX;

vector<mint> A(n);
for(mint &x : A)
x = gen.uniform<int>(0, MOD - 1);

printf("%d %d\n", n, q);
for (int i = 0; i < q; i++) {
int ty = gen.uniform_bool();
int a = gen.uniform(0, n - 1);
int b = gen.uniform(0, n - 1);
if (ty == 1) {
printf("%d %d %d\n", ty, a, b);
} else {
mint x;
if (gen.uniform_bool())
x = gen.uniform<int>(0, MOD - 1);
else
x = op(inv(A[b]), A[a]);
printf("%d %d %d %d\n", ty, a, b, x.val());
}
}
return 0;
}
103 changes: 103 additions & 0 deletions datastructure/unionfind_with_potential/gen/path.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
#include "random.h"
#include "../params.h"
#include "../sol/acl.h"
#include <cassert>
#include <cstdio>
#include <cstdlib>
#include <numeric>
#include <utility>
#include <vector>
#include <algorithm>

using namespace std;
using namespace atcoder;

using mint = modint998244353;

mint id() { return 0; }
mint op(const mint &a, const mint &b) { return a + b; }
mint inv(const mint &a) { return -a; }

int main(int, char *argv[]) {
const long long seed = std::atoll(argv[1]);
Random gen(seed);

const int N_AND_Q = std::min(N_MAX, Q_MAX);

struct query_type {
int t;
int u;
int v;
};

std::vector<query_type> qs(N_AND_Q);

// unused-but-set-variable が誤反応するようなので、抑制する
#if defined(__GNUC__) && !defined(__llvm__) && !defined(__INTEL_COMPILER)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
#endif
if (seed == 0 || seed == 1) {
// parent[v] = u 最悪ケース
const int K = 2 * N_AND_Q / 3;
for (int i = 0; i != K; i += 1) {
auto &[t, u, v] = qs[i];
t = 0;
u = i + 1;
v = 0;
}
for (int i = K; i != N_AND_Q; i += 1) {
auto &[t, u, v] = qs[i];
t = 1;
u = 0;
v = 1;
}
}
if (seed == 2 || seed == 3) {
// parent[v] = u 深さ最大
for (int i = 0; i != N_AND_Q - 1; i += 1) {
auto &[t, u, v] = qs[i];
t = 0;
u = i + 1;
v = i;
}
{
auto &[t, u, v] = qs[N_AND_Q - 1];
t = 0;
u = 0;
v = N_AND_Q - 1;
}
}
if (seed == 1 || seed == 3) {
// u, v 反転
for (auto &query : qs) {
std::swap(query.u, query.v);
}
}
#if defined(__GNUC__) && !defined(__llvm__) && !defined(__INTEL_COMPILER)
#pragma GCC diagnostic pop
#endif

vector<mint> A(N_AND_Q);
for(mint &x : A)
x = gen.uniform<int>(0, MOD - 1);

std::vector<int> p(N_AND_Q);
std::iota(p.begin(), p.end(), 0);
gen.shuffle(p.begin(), p.end());
std::printf("%d %d\n", N_AND_Q, N_AND_Q);
for (const auto &[t, u, v] : qs) {
if (t == 1) {
std::printf("%d %d %d\n", t, p[u], p[v]);
} else {
mint x;
if (gen.uniform_bool())
x = gen.uniform<int>(0, MOD - 1);
else
x = op(inv(A[v]), A[u]);
std::printf("%d %d %d %d\n", t, p[u], p[v], x.val());
}
}

return 0;
}
44 changes: 44 additions & 0 deletions datastructure/unionfind_with_potential/gen/random.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#include <iostream>
#include "random.h"
#include "../sol/acl.h"
#include "../params.h"

using namespace std;
using namespace atcoder;

using mint = modint998244353;

mint id() { return 0; }
mint op(const mint &a, const mint &b) { return a + b; }
mint inv(const mint &a) { return -a; }

int main(int, char* argv[]) {

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

int n = gen.uniform<int>(1, N_MAX);
int q = gen.uniform<int>(1, Q_MAX);

vector<mint> A(n);
for(mint &x : A)
x = gen.uniform<int>(0, MOD - 1);

printf("%d %d\n", n, q);
for (int i = 0; i < q; i++) {
int ty = gen.uniform_bool();
int a = gen.uniform(0, n - 1);
int b = gen.uniform(0, n - 1);
if (ty == 1) {
printf("%d %d %d\n", ty, a, b);
} else {
mint x;
if (gen.uniform_bool())
x = gen.uniform<int>(0, MOD - 1);
else
x = op(inv(A[b]), A[a]);
printf("%d %d %d %d\n", ty, a, b, x.val());
}
}
return 0;
}
38 changes: 38 additions & 0 deletions datastructure/unionfind_with_potential/hash.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
"example_00.in": "f4fa01a168d9b818f8dbd66f10d4d1c6f4b7f1001fd6bf382c30d23f75298913",
"example_00.out": "ec6959b4802b196473186e786f118528fa08d8eb4c73e3dffcc7404f20330f1f",
"max_random_00.in": "4e44a642c69d8912601aca34d12dc87d7b32827b65808236400ee9de59b50fb1",
"max_random_00.out": "c5997dec97b8b313b64627605f7aa870f5d1aa241cb1c690fda04040d299f31e",
"max_random_01.in": "40006c09d78339e11e97c542b3ff49fedaabeb4a87750a846b1fd8feb2cf45ed",
"max_random_01.out": "3a6f693e0ca0ce15d47019806d92989c691cdbc2ac3da425d518eeec069ad521",
"max_random_02.in": "95bc849d1702d520baf348117740ad9ecee47d0d8db464332222edea19fa72ee",
"max_random_02.out": "8639d7edfe0796281f6437e15ccd79ecc28317f52773f3b93ea4ff194e17d784",
"path_00.in": "e00302d2af330494a4580aeea6334d0b299d02343e91ecfaf0b445339d03877a",
"path_00.out": "5f700d24f95cfa31974d55e9845491aaad07efa4461acd438d40bbe7cc68dbd3",
"path_01.in": "ddf9f1d5e8adf791b88a005e436623b46ceb326764d0a11fabee90380a12d653",
"path_01.out": "17bffd4c31bf4fce60d543dbed7b13b2502291282582145574d30280f1096cec",
"path_02.in": "0362f1bc1f24ddaa06901ed849146e58645267d5c469f0cac09e5b830d80a9a9",
"path_02.out": "92e0ea193ae02c22dcf47b2c3e0b5e48f5a79e773a15eef190898b861773aaf2",
"path_03.in": "95209543e3d7621237e88575f4f6559e397856c6f215b1b4a8e4e038de1de253",
"path_03.out": "92e0ea193ae02c22dcf47b2c3e0b5e48f5a79e773a15eef190898b861773aaf2",
"random_00.in": "175ad842afcc62e2629aa8d0495a0df45d58a594f740a7d0c6e748e87f9ec669",
"random_00.out": "169a46fea9da106bc0ec378539db06ae10c74e28befa80d476bc3d7d9fbe5a11",
"random_01.in": "b95be4cea990478ce62affff56b126daec318c3a27689b125a055212f7ebb09b",
"random_01.out": "befac958d7564504f25830b7849582dea7c48ebb581a3b2eb90ecc2dd5a9a7d9",
"random_02.in": "4118a5833803e881f3ca886aa0553915b68f834f47523c8ec67105967250b317",
"random_02.out": "cc16708c76770b88ad2e8c0e980bce2fc2eea5f18f0a3aeec04e2ba830679181",
"random_03.in": "8da25241ad57a7af4f72686de801c31bb2052a3b5aa270db09a29268554a931c",
"random_03.out": "c8cab222e36c7a03628fa438b7ae60ecafd86500d0ab1fece4b9f240a177a6d8",
"random_04.in": "39bafe10abbf229c763c039951034263e94c27cfdfc433b234eaa32bc1b7140e",
"random_04.out": "4b135c466053ff03409af8ebf982e3ec1b719407ec070028c0d4c743f2429d92",
"random_05.in": "d74b0c6aa235cedb84333ed7b7a3b008c372ef564e553b57dfaeeb252372d9d8",
"random_05.out": "d2eb98a13222c0b02a3530bd92571c471e17ca9508a14b85a7ae5d6e6e825d1f",
"random_06.in": "1eaddcacca38125bb5064001424c10be2a3132c19718f009b1d106791bd7545c",
"random_06.out": "d84d66c6dd7d120eab47ab4a4ca9fed949abe24a18bd17847b84675c05ac75d0",
"random_07.in": "2601d39a88ad5a834177b917b1f2af9e60dce6d4ec47827d24193fbca62d244f",
"random_07.out": "6c52b9ecd7c50f42c4e7508d1c29336cac0b8695e1b2101e0cf2582ad92da4f8",
"random_08.in": "25cf75eea57af237a8ef21b8bccbfa99107681dd619f24eeda8b02315ef45d7a",
"random_08.out": "9916adfa8710a76a826a02a3f1b816e5d6db134745d729af87a32b41f79e2d20",
"random_09.in": "be1b0ba4002df6acccc9bdad202642e93f7d9beec0bb2ecf7beb0f5e3b75d341",
"random_09.out": "ef049e35e660d9dc6c526b4d59998b0b0dba4ade71e58cbcad80007f0f277ffd"
}
25 changes: 25 additions & 0 deletions datastructure/unionfind_with_potential/info.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
title = 'Unionfind with Potential'
timelimit = 5.0
forum = 'https://github.com/yosupo06/library-checker-problems/issues/1194'

[[tests]]
name = "example.in"
number = 1
[[tests]]
name = "random.cpp"
number = 10
[[tests]]
name = "max_random.cpp"
number = 3
[[tests]]
name = "path.cpp"
number = 4

[[solutions]]
name = "naive.cpp"
expect = "TLE"

[params]
N_MAX = 200_000
Q_MAX = 200_000
MOD = 998_244_353
Loading

0 comments on commit 3753a29

Please sign in to comment.