QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#608582#6123. JAG Graph Isomorphismqtoq#WA 1ms3968kbC++177.0kb2024-10-03 23:24:252024-10-03 23:24:25

Judging History

你现在查看的是最新测评结果

  • [2024-10-03 23:24:25]
  • 评测
  • 测评结果:WA
  • 用时:1ms
  • 内存:3968kb
  • [2024-10-03 23:24:25]
  • 提交

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 ;
  }
  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: 1ms
memory: 3668kb

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: 3656kb

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: 3600kb

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: 1ms
memory: 3900kb

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: 3796kb

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: 3968kb

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