답안 #165645

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
165645 2019-11-28T03:54:31 Z _qVp_ Zamjene (COCI16_zamjene) C++14
140 / 140
2408 ms 132912 KB
#include <bits/stdc++.h>

using namespace std;

const int base = 1234577;
const int md = 1e6 + 10;

int n, T;
int p[md], q[md], sz[md], lab[md];
long long pw[md], id[md], val[md];
long long pairs;
unordered_map < long long, int > diff_nodes; 

void addNode(int sign, long long diff, int num) {
    if (diff != 0) 
        pairs += sign * num * diff_nodes[-diff];
    diff_nodes[diff] += sign * num;
}

int root(int x) {
    if (lab[x] == x)
        return x;
    return lab[x] = root(lab[x]);
}

void init() {
    cin >> n >> T;
    pw[0] = 1;
    for(int i = 1; i < md; i++)
        pw[i] = pw[i - 1] * base;
    for(int i = 1; i <= n; i++) {
        cin >> p[i];
        q[i] = p[i];
        lab[i] = i;
        sz[i] = 1;
    }
    sort(q + 1, q + 1 + n);
    for(int i = 1; i <= n; i++) {
        id[i] = pw[q[i]];
        val[i] = pw[p[i]];
        //cout << id[i] << " " << val[i] << endl;
        addNode(1, id[i] - val[i], sz[i]);
    }
}

void add(int sign, int ru, int u, int v) {
    id[ru] += sign * pw[u];
    val[ru] += sign * pw[v];
    sz[ru] += sign; 
}

void merges(int u, int v) {
    int ru = root(u), rv = root(v);
    if (ru == rv)
        return ;
    addNode(-1, id[ru] - val[ru], sz[ru]);
    addNode(-1, id[rv] - val[rv], sz[rv]);
    lab[rv] = ru;
    sz[ru] += sz[rv];
    id[ru] += id[rv];
    val[ru] += val[rv];
    //cout << id[ru] << " " << val[ru] << endl;
    addNode(1, id[ru] - val[ru], sz[ru]);
}

int main() {
    //clock_t times = clock();
    //freopen("test.in", "r", stdin);
    //freopen("test.out", "w", stdout);
    ios_base::sync_with_stdio(0); cin.tie(0);
    init();
    while (T--) {
        int type;
        cin >> type;
        if (type == 1) {
            int u, v;
            cin >> u >> v;
            int ru = root(u), rv = root(v);
            if (ru == rv) {
                swap(p[u], p[v]);
                continue;
            }
            addNode(-1, id[ru] - val[ru], sz[ru]);
            addNode(-1, id[rv] - val[rv], sz[rv]);
            add(-1, ru, u, p[u]);
            add(-1, rv, v, p[v]);

            swap(p[u], p[v]);

            add(1, ru, u, p[u]);
            add(1, rv, v, p[v]);
            addNode(1, id[ru] - val[ru], sz[ru]);
            addNode(1, id[rv] - val[rv], sz[rv]);
        } else if (type == 2) {
            int u, v;
            cin >> u >> v;
            merges(u, v);
        } else if (type == 3) {
            //cout << diff_nodes[0]  << endl;
            if (diff_nodes[0] == n)
                cout << "DA\n";
            else cout << "NE\n";
        } else {
            cout << pairs << '\n';
        }
    }
    //cout << fixed << setprecision(3);
  //cerr << (1.0 * clock() - times) / (CLOCKS_PER_SEC);
    return 0;
}
# 결과 실행 시간 메모리 Grader output
1 Correct 23 ms 8184 KB Output is correct
2 Correct 9 ms 8184 KB Output is correct
3 Correct 9 ms 8184 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 9 ms 8184 KB Output is correct
2 Correct 9 ms 8184 KB Output is correct
3 Correct 9 ms 8184 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 9 ms 8188 KB Output is correct
2 Correct 9 ms 8056 KB Output is correct
3 Correct 9 ms 8184 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 9 ms 8184 KB Output is correct
2 Correct 10 ms 8184 KB Output is correct
3 Correct 10 ms 8312 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 9 ms 8312 KB Output is correct
2 Correct 10 ms 8184 KB Output is correct
3 Correct 10 ms 8312 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 14 ms 8568 KB Output is correct
2 Correct 15 ms 8696 KB Output is correct
3 Correct 14 ms 8696 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 68 ms 11796 KB Output is correct
2 Correct 126 ms 13060 KB Output is correct
3 Correct 98 ms 14984 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 829 ms 35356 KB Output is correct
2 Correct 1842 ms 92980 KB Output is correct
3 Correct 2408 ms 132912 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1370 ms 69080 KB Output is correct
2 Correct 1813 ms 91796 KB Output is correct
3 Correct 1184 ms 73140 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 859 ms 46172 KB Output is correct
2 Correct 1351 ms 71624 KB Output is correct
3 Correct 1168 ms 73080 KB Output is correct