QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#608584 | #6123. JAG Graph Isomorphism | qtoq# | WA | 1ms | 3840kb | C++17 | 7.0kb | 2024-10-03 23:25:15 | 2024-10-03 23:25:21 |
Judging History
answer
#include <bits/stdc++.h>
using namespace std;
template<typename T_container, typename T = typename enable_if<!is_same<T_container, string>::value, typename T_container::value_type>::type> ostream& operator<<(ostream &os, const T_container &v) { os << '{'; string sep; for (const T &x : v) os << sep << x, sep = ", "; return os << '}'; }
void dbg_out() { cerr << endl; }
template<typename Head, typename... Tail> void dbg_out(Head H, Tail... T) { cerr << ' ' << H; dbg_out(T...); }
#ifdef ONPC
#define deb(...) cerr << '[' << __FILE__ << ':' << __LINE__ << "] (" << #__VA_ARGS__ << "):", dbg_out(__VA_ARGS__)
#else
#pragma GCC optimize("O3,unroll-loops")
#pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt")
#define deb(...)
#endif
// c++ short types
#define vt vector
//typedef long long ll;
typedef long double ld;
void whattime() { cout << "finished in " << clock() * 1.0 / CLOCKS_PER_SEC << " sec" << endl; }
// const int mod = 1e9 + 7;
const int mod = 998244353;
const int inf = 1e9;
const int64_t infll = 1e13;
bool debug = false;
const ld eps = 1e-9;
const ld pi = acos(-1);
mt19937_64 rng((int) chrono::steady_clock::now().time_since_epoch().count());
uint64_t h(uint64_t x) {
return x * x * x * 1237123 + 19260817;
}
uint64_t f(uint64_t x) {
int64_t cur = h(x & ((1 << 31) - 1)) + h(x >> 31);
return cur;
}
vector<vector<int>> adj;
vector<bool> visited;
vector<int> parent;
int cycle_start, cycle_end;
bool dfs(int v, int par) { // passing vertex and its parent vertex
visited[v] = true;
for (int u : adj[v]) {
if(u == par) continue; // skipping edge to parent vertex
if (visited[u]) {
cycle_end = v;
cycle_start = u;
return true;
}
parent[u] = v;
if (dfs(u, parent[u]))
return true;
}
return false;
}
vt<int> find_cycle(int n) {
visited.assign(n, false);
parent.assign(n, -1);
cycle_start = -1;
for (int v = 0; v < n; v++) {
if (!visited[v] && dfs(v, parent[v]))
break;
}
if (cycle_start == -1) {
assert(false);
} else {
vector<int> cycle;
cycle.push_back(cycle_start);
for (int v = cycle_end; v != cycle_start; v = parent[v])
cycle.push_back(v);
cycle.push_back(cycle_start);
return cycle;
}
return {};
}
vt<uint64_t> get(vt<vt<int>> g) {
int n = (int)g.size();
adj = g;
vt<int> cycle = find_cycle(n);
vt<int> is_cycle(n, false);
for(auto x: cycle) {
is_cycle[x] = true;
}
vt<uint64_t> res;
cycle.pop_back();
int id = 0;
map<vt<int>, int> ha;
for(auto i: cycle) {
auto Dfs = [&](auto self, int e, int p) -> int {
vt<int> hs;
for(auto to:g[e]) if(to != p and !is_cycle[to]) {
hs.push_back(self(self,to,e));
}
sort(hs.begin(), hs.end());
if(ha.count(hs)) {
return ha[hs];
}
return ha[hs] = id++;
};
res.push_back(Dfs(Dfs, i, i));
}
return res;
}
void solve() {
int n; cin >> n;
vt<vt<int>> g(n);
for(int i = 0; i < n; ++i) {
int a, b; cin >> a >> b;
g[--a].push_back(--b);
g[b].push_back(a);
}
vt<uint64_t> a = get(g);
for(auto &v: g) {
v.clear();
}
for(int i = 0; i < n; ++i) {
int a, b; cin >> a >> b;
g[--a].push_back(--b);
g[b].push_back(a);
}
vt<uint64_t> b = get(g);
if(a.size() != b.size()) {
cout << "No\n";
return ;
}
{
vt<uint64_t> c = a, d = b;
sort(c.begin(), c.end());
sort(d.begin(), d.end());
if(c != d) {
cout << "No\n";
return;
}
map<uint64_t, int> ids;
for(auto x: c) {
ids[x];
}
int id = 0;
for(auto& [val, i]: ids) {
i = id++;
}
for(auto &x: a) {
x = ids[x];
}
for(auto &x: b) {
x = ids[x];
}
}
n = (int)a.size();
if(n <= 1000) {
for(int i = 0; i < n; ++i) {
a.push_back(i);
}
for(int i = 0; i < n; ++i) {
bool flag = true;
for(int j = 0; j < n; ++j) {
flag = flag && a[i+j] == b[j];
}
if(flag) {
cout << "Yes\n";
return ;
}
flag = 1;
for(int j = 0; j < n; ++j) {
flag = flag && a[i+j] == b[n-j-1];
}
if(flag) {
cout << "Yes\n";
return ;
}
}
reverse(a.begin(), a.end());
cout << "No\n";
return ;
}
assert(false);
const int m = 1e9 + 123;
const int m1 = 1e9 +123, m2 = 1e9 + 7;
const int p1 = rand() % (m1 - 256) + 256;
const int p2 = rand() % (m2 - 256) + 256;
int k = (int)a.size();
vt<vt<int>> pw(k, vt<int>(2, 1));
for(int i = 1; i < k; ++i) {
pw[i][0] = (pw[i-1][0] * 1ll * p1) % m1;
pw[i][1] = (pw[i-1][1] * 1ll * p1) % m1;
}
{
array<int, 2> hash = {0,0};
for(auto x: a) {
hash[0] = (hash[0] * 1ll * p1 + x) % m1;
hash[1] = (hash[1] * 1ll * p2 + x) % m2;
}
vt<array<int, 2>> pref(k, {0,0});
for(int i = 0; i < k; ++i) {
pref[i][0] = pw[i][0] * 1ll * b[i] % m1;
pref[i][1] = pw[i][1] * 1ll * b[i] % m2;
if(i) {
pref[i][0] = (pref[i][0] + pref[i-1][0]) % m1;
pref[i][1] = (pref[i][1] + pref[i-1][1]) % m2;
}
}
if(pref.back() == hash) {
cout << "Yes\n";
return ;
}
array<int, 2> cur = {0, 0};
for(int i = k - 1; i >= 1; --i) {
cur[0] = (cur[0] * 1ll * p1 + b[i]) % m1;
cur[1] = (cur[1] * 1ll * p2 + b[i]) % m2;
auto z = cur;
z[0] = (z[0] + pw[k-i][0] * 1ll * pref[i-1][0]) % m1;
z[1] = (z[1] + pw[k-i][1] * 1ll * pref[i-1][1]) % m2;
if(z == hash) {
cout << "Yes\n";
return ;
}
}
}
deb(a, b);
reverse(a.begin(), a.end());
{
array<int, 2> hash = {0,0};
for(auto x: a) {
hash[0] = (hash[0] * 1ll * p1 + x) % m1;
hash[1] = (hash[1] * 1ll * p2 + x) % m2;
}
vt<array<int, 2>> pref(k, {0,0});
for(int i = 0; i < k; ++i) {
pref[i][0] = pw[i][0] * 1ll * b[i] % m1;
pref[i][1] = pw[i][1] * 1ll * b[i] % m2;
if(i) {
pref[i][0] = (pref[i][0] + pref[i-1][0]) % m1;
pref[i][1] = (pref[i][1] + pref[i-1][1]) % m2;
}
}
if(pref.back() == hash) {
cout << "Yes\n";
return ;
}
array<int, 2> cur = {0, 0};
for(int i = k - 1; i >= 1; --i) {
cur[0] = (cur[0] * 1ll * p1 + b[i]) % m1;
cur[1] = (cur[1] * 1ll * p2 + b[i]) % m2;
auto z = cur;
z[0] = (z[0] + pw[k-i][0] * 1ll * pref[i-1][0]) % m1;
z[1] = (z[1] + pw[k-i][1] * 1ll * pref[i-1][1]) % m2;
if(z == hash) {
cout << "Yes\n";
return ;
}
}
}
cout << "No\n";
}
int main()
{
ios::sync_with_stdio(false); cin.tie(nullptr);
int tt = 1;;
if(debug) {
tt = 1e3;
} else {
}
for(int t = 0; t < tt; ++t) {
solve();
}
#ifdef ONPC
whattime();
#endif
return 0;
}
详细
Test #1:
score: 100
Accepted
time: 0ms
memory: 3684kb
input:
4 1 2 2 3 2 4 3 4 1 2 1 3 1 4 3 4
output:
Yes
result:
ok answer is YES
Test #2:
score: 0
Accepted
time: 0ms
memory: 3600kb
input:
4 1 2 2 3 3 4 1 4 1 2 1 3 1 4 3 4
output:
No
result:
ok answer is NO
Test #3:
score: 0
Accepted
time: 0ms
memory: 3716kb
input:
6 1 2 1 3 2 5 2 6 3 5 4 6 1 5 1 6 2 4 2 5 2 6 3 4
output:
Yes
result:
ok answer is YES
Test #4:
score: 0
Accepted
time: 0ms
memory: 3840kb
input:
903 835 491 695 797 411 56 636 367 122 715 775 564 199 77 31 593 654 460 330 25 555 345 36 527 768 760 378 753 291 51 676 73 227 883 310 389 656 259 603 836 369 901 347 231 543 259 66 772 301 592 711 738 507 499 425 462 27 458 257 328 628 83 184 645 805 495 491 311 635 874 615 259 39 193 715 673 636...
output:
No
result:
ok answer is NO
Test #5:
score: 0
Accepted
time: 1ms
memory: 3828kb
input:
700 520 12 414 245 592 324 396 343 365 93 611 99 163 524 327 310 436 373 646 392 642 15 698 393 599 682 427 341 383 14 218 330 453 441 647 223 14 26 36 118 229 27 56 604 497 177 621 352 178 349 372 257 45 533 44 407 110 343 66 468 564 253 200 27 80 62 50 201 130 5 190 12 140 643 635 130 352 465 223 ...
output:
No
result:
ok answer is NO
Test #6:
score: -100
Wrong Answer
time: 1ms
memory: 3672kb
input:
350 40 299 79 166 204 324 281 292 63 25 326 188 279 70 64 153 145 121 93 188 283 187 339 1 11 10 330 146 124 45 295 65 208 60 131 39 328 21 181 78 276 5 121 62 81 136 248 78 51 115 87 159 346 338 251 133 306 64 298 183 161 42 14 207 5 73 259 89 269 194 334 129 118 82 50 314 246 72 180 68 166 283 249...
output:
No
result:
wrong answer expected YES, found NO