QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#57829#2515. Graph CardsSa3tElSefrAC ✓16424ms69228kbC++204.0kb2022-10-23 04:54:302022-10-23 04:54:32

Judging History

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

  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2022-10-23 04:54:32]
  • 评测
  • 测评结果:AC
  • 用时:16424ms
  • 内存:69228kb
  • [2022-10-23 04:54:30]
  • 提交

answer

#pragma GCC optimize("O3")
#pragma GCC optimize ("unroll-loops")
#pragma GCC target("avx,avx2,fma")

#include <bits/stdc++.h>

#define ll long long
#define ld  double
using namespace std;

const int N = 1e6 + 5, mod = 998244353;

vector<int> path, adj[N], s;

set<vector<int> > st;

int par[N];
int inCycle[N];

bool dfs(int u, int v, int par) {
    path.push_back(u);
    if(u == v)
        return true;
    for(auto to : adj[u]) {
        if(to == par) continue;
        if(dfs(to, v, u))
            return true;
    }
    path.pop_back();
    return false;
}

int id;

map<vector<int>, int> mp;


int dfs_col(int node, int par) {
    vector<int> cur;
    for(auto i: adj[node]) {
        if(i == par || inCycle[i]) continue;
//        cout << "EDGE " << node << ' ' << i << endl;
        cur.push_back(dfs_col(i, node));
    }
    sort(cur.begin(), cur.end());
    if(mp.find(cur) == mp.end()) mp[cur] = id++;
    return mp[cur];
}


void init() {
    id = 2;
    mp.clear();
    mp[vector<int>()] = 1;
    st.clear();

}

int findPar(int u) {
    if(par[u] == u) return u;
    return par[u] = findPar(par[u]);
}

bool sameSet(int u, int v) {
    return findPar(u) == findPar(v);
}

void join(int u, int v) {
    u = findPar(u);
    v = findPar(v);
    par[u] = v;
}

void initInBetween(int n) {
    path.clear();
    for(int i = 0; i <= n; i++) {
        adj[i].clear();
        inCycle[i] = 0;
    }
    s.clear();
    iota(par, par + n + 1, 0);
}


int min_cyc()
{
    int n = s.size();
    int res = 0;
    for (int l = 0; l < n; )
    {
        res = l;
        int r = l, p = l + 1;
        for (; r < n; ++r, ++p) /// If there is such string found, then its length wont exceed |s|
        {
            int c = (p < n) ? s[p] : s[p - n]; /// to avoid modulo
            if (s[r] > c) break;
            if (s[r] < c) r = l - 1;
        }
        l = max(r, l + p - r); /// just skip those (s2 = sx + sx + ... + sx + sy) cases
    }
    return res;
}


int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);


    int tt;
    cin >> tt;
    while(tt--) {
        init();
        int n;
        cin >> n;
        for(int t = 0; t < n; t++) {
            int k;
            cin >> k;
            initInBetween(k);
            int from, to;
            for(int j = 0; j < k; j++) {
                int u, v;
                cin >> u >> v;
                adj[u].push_back(v);
                adj[v].push_back(u);
                if(sameSet(u, v)) {
                    from = u;
                    to = v;
                }
                join(u, v);
            }
            dfs(from, to, 0);
//            cout << "PATH\n";
            for(auto i: path) {
//                cout << i << ' ';
                inCycle[i] = 1;
            }
//            cout << '\n';

            for(auto i: path) {
                s.push_back(dfs_col(i, 0));
//                cout << s.back() << ' ';
            }
//            cout << endl;

            int idx = min_cyc();
            vector<int> lexoSmallest;
            for(int i = idx; i < (int) path.size(); i++) {
                lexoSmallest.push_back(s[i]);
            }
            for(int i = 0; i < idx; i++) {
                lexoSmallest.push_back(s[i]);
            }

            reverse(s.begin(), s.end());

            idx = min_cyc();

            vector<int> lex2;

            for(int i = idx; i < (int) path.size(); i++) {
                lex2.push_back(s[i]);
            }
            for(int i = 0; i < idx; i++) {
                lex2.push_back(s[i]);
            }

            st.insert(min(lexoSmallest, lex2));
//            for(auto i: lexoSmallest) cout << i << ' ';
//            cout << '\n';
        }
        cout << (int) st.size() << '\n';
        // cout << '\n';
    }





    return 0;
}

/*
 1
3
9 1 4 4 2 2 3 3 5 5 7 7 6 6 4 7 8 8 9
9 1 2 2 5 5 7 7 6 6 3 3 1 2 4 7 9 9 8
9 1 2 2 5 5 4 4 1 4 7 7 8 8 6 8 9 5 3
 */

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 5ms
memory: 27092kb

input:

1
2
4 1 2 2 3 3 1 1 4
4 1 2 2 3 3 1 2 4

output:

1

result:

ok single line: '1'

Test #2:

score: 0
Accepted
time: 7ms
memory: 28936kb

input:

2
2
4 1 2 2 3 3 1 1 4
5 1 2 2 3 3 1 2 4 2 5
3
9 1 2 2 5 5 7 7 6 6 3 3 1 2 4 7 9 9 8
9 1 4 4 2 2 3 3 5 5 7 7 6 6 4 7 8 8 9
9 1 2 2 5 5 4 4 1 4 7 7 8 8 6 8 9 5 3

output:

2
2

result:

ok 2 lines

Test #3:

score: 0
Accepted
time: 12269ms
memory: 46604kb

input:

30
332526
3 3 2 3 1 2 1
3 2 3 3 1 1 2
3 1 3 1 2 3 2
3 3 2 2 1 1 3
3 2 1 2 3 1 3
3 1 3 1 2 3 2
3 1 2 2 3 3 1
3 2 1 2 3 1 3
3 3 1 3 2 1 2
3 1 3 1 2 3 2
3 1 3 3 2 2 1
3 1 2 2 3 3 1
3 3 1 3 2 1 2
3 2 1 2 3 1 3
3 3 2 2 1 1 3
3 1 2 1 3 2 3
3 1 2 1 3 2 3
3 2 3 2 1 3 1
3 1 2 1 3 2 3
3 3 1 1 2 2 3
3 1 3 1 2 ...

output:

1
4
5
89
93
242
628
1575
3401
5703
7718
8888
9258
9355
9356
9203
9211
89
239
648
1739
4541
10352
19037
27089
31567
33030
33068
32480
31503

result:

ok 30 lines

Test #4:

score: 0
Accepted
time: 10376ms
memory: 38480kb

input:

30
333333
3 2 1 2 3 3 1
3 1 2 3 2 3 1
3 3 2 1 3 1 2
3 2 3 2 1 3 1
3 2 3 2 1 1 3
3 1 2 3 2 3 1
3 3 1 2 1 3 2
3 1 3 1 2 3 2
3 1 3 2 3 1 2
3 2 1 3 2 3 1
3 2 3 1 2 1 3
3 3 1 1 2 3 2
3 3 2 3 1 1 2
3 2 1 3 1 3 2
3 3 2 1 2 3 1
3 3 2 1 2 1 3
3 2 3 2 1 1 3
3 1 2 3 2 3 1
3 3 1 1 2 3 2
3 1 3 1 2 2 3
3 1 2 3 2 ...

output:

1
2
5
13
33
89
240
653
1771
4753
11868
24982
40524
51128
54690
54119
52143
49848
47551
45441
43471
41664
40000
38461
37037
35714
34482
33333
32258
31250

result:

ok 30 lines

Test #5:

score: 0
Accepted
time: 16424ms
memory: 69228kb

input:

30
2
500000 12446 494050 179161 216388 282442 232792 428247 130742 87062 493860 276791 469755 342468 58973 93535 429405 5662 112197 121541 62083 28611 427877 376918 349780 372239 58010 457751 308686 448844 473714 151350 480692 152372 415617 311966 298916 302690 200753 75481 396263 318635 79619 39930...

output:

1
2
2
1
1
2
2
1
1
2
2
1
1
2
2
1
1
2
2
1
1
2
2
1
1
2
2
1
1
2

result:

ok 30 lines

Test #6:

score: 0
Accepted
time: 215ms
memory: 48180kb

input:

1
4
240000 1 2 2 3 3 4 4 7 1 5 2 6 7 8 8 9 9 10 10 13 7 11 8 12 13 14 14 15 15 16 16 19 13 17 14 18 19 20 20 21 21 22 22 25 19 23 20 24 25 26 26 27 27 28 28 31 25 29 26 30 31 32 32 33 33 34 34 37 31 35 32 36 37 38 38 39 39 40 40 43 37 41 38 42 43 44 44 45 45 46 46 49 43 47 44 48 49 50 50 51 51 52 52...

output:

2

result:

ok single line: '2'