結果

問題 No.1054 Union add query
ユーザー Ricky_ponRicky_pon
提出日時 2020-06-03 21:54:35
言語 C++17
(gcc 12.3.0 + boost 1.83.0)
結果
AC  
実行時間 156 ms / 2,000 ms
コード長 2,280 bytes
コンパイル時間 2,008 ms
コンパイル使用メモリ 205,916 KB
実行使用メモリ 13,060 KB
最終ジャッジ日時 2023-08-17 06:42:25
合計ジャッジ時間 5,791 ms
ジャッジサーバーID
(参考情報)
judge11 / judge12
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 1 ms
4,380 KB
testcase_01 AC 1 ms
4,376 KB
testcase_02 AC 1 ms
4,380 KB
testcase_03 AC 147 ms
4,956 KB
testcase_04 AC 156 ms
12,608 KB
testcase_05 AC 141 ms
4,380 KB
testcase_06 AC 141 ms
6,900 KB
testcase_07 AC 129 ms
6,940 KB
testcase_08 AC 136 ms
7,224 KB
testcase_09 AC 149 ms
13,060 KB
testcase_10 AC 102 ms
12,868 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#include <bits/stdc++.h>
#define For(i, a, b) for(int (i)=(int)(a); (i)<(int)(b); ++(i))
#define rFor(i, a, b) for(int (i)=(int)(a)-1; (i)>=(int)(b); --(i))
#define rep(i, n) For((i), 0, (n))
#define rrep(i, n) rFor((i), (n), 0)
#define fi first
#define se second
using namespace std;
typedef long long lint;
typedef unsigned long long ulint;
typedef pair<int, int> pii;
typedef pair<lint, lint> pll;
template<class T> bool chmax(T &a, const T &b){if(a<b){a=b; return true;} return false;}
template<class T> bool chmin(T &a, const T &b){if(a>b){a=b; return true;} return false;}
template<class T> T div_floor(T a, T b){
    if(b < 0) a *= -1, b *= -1;
    return a>=0 ? a/b : (a+1)/b-1;
}
template<class T> T div_ceil(T a, T b){
    if(b < 0) a *= -1, b *= -1;
    return a>0 ? (a-1)/b+1 : a/b;
}

constexpr lint mod = 1e9+7;
constexpr lint INF = mod * mod;
constexpr int MAX = 200010;

template<typename T> struct WeightedUnionFind{
    vector<int> par;
    vector<T> diff, val;

    WeightedUnionFind(int n){
        par.resize(n, -1);
        diff.resize(n, 0);
        val.resize(n, 0);
    }

    bool is_root(int x){
        return par[x] < 0;
    }

    int find(int x){
        if(is_root(x)) return x;
        int r = find(par[x]);
        diff[x] += diff[par[x]];
        return par[x] = r;
    }

    int size(int x){
        return -par[find(x)];
    }

    T weight(int x){
        if(is_root(x)) return val[x];
        return val[find(x)] + diff[x];
    }

    void add(int x, T w){
        val[find(x)] += w;
    }

    bool unite(int x, int y, T d){
        find(x); find(y);
        d += diff[x] - diff[y];
        x = find(x); y = find(y);
        if(x == y) return false;
        if(size(x) < size(y)) swap(x, y), d = -d;
        par[x] += par[y];
        par[y] = x;
        diff[y] = d;
        return true;
    }
};

int main(){
    int n, q;
    scanf("%d%d", &n, &q);
    WeightedUnionFind<lint> uf(n);
    rep(qq, q){
        int t, a, b;
        scanf("%d%d%d", &t, &a, &b);
        if(t == 1){
            --a; --b;
            uf.unite(a, b, uf.weight(b) - uf.weight(a));
        }
        else if(t == 2){
            --a;
            uf.add(a, b);
        }
        else{
            --a;
            printf("%lld\n", uf.weight(a));
        }
    }
}
0