結果
| 問題 |
No.1054 Union add query
|
| コンテスト | |
| ユーザー |
momohara
|
| 提出日時 | 2020-05-17 04:52:51 |
| 言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 194 ms / 2,000 ms |
| コード長 | 3,027 bytes |
| コンパイル時間 | 2,050 ms |
| コンパイル使用メモリ | 177,872 KB |
| 実行使用メモリ | 14,956 KB |
| 最終ジャッジ日時 | 2024-09-24 11:56:58 |
| 合計ジャッジ時間 | 5,332 ms |
|
ジャッジサーバーID (参考情報) |
judge2 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 8 |
ソースコード
#include <bits/stdc++.h>
using namespace std;
#define rep(i,m,n) for(int (i)=(int)(m);i<(int)(n);++i)
#define rep2(i,m,n) for(int (i)=(int)(n)-1;i>=(int)(m);--i)
#define REP(i,n) rep(i,0,n)
#define REP2(i,n) rep2(i,0,n)
#define FOR(i,c) for(decltype((c).begin())i=(c).begin();i!=(c).end();++i)
#define all(hoge) (hoge).begin(),(hoge).end()
#define en '\n'
using ll = long long;
using ull = unsigned long long;
template <class T> using vec = vector<T>;
template <class T> using vvec = vector<vec<T>>;
typedef pair<ll, ll> P;
constexpr long long INF = 1LL << 60;
constexpr int INF_INT = 1 << 25;
//constexpr long long MOD = (ll) 1e9 + 7;
constexpr long long MOD = 998244353LL;
typedef vector<ll> Array;
typedef vector<Array> Matrix;
template<class T> inline bool chmin(T& a, T b) {
if (a > b) {
a = b;
return true;
}
return false;
}
template<class T> inline bool chmax(T& a, T b) {
if (a < b) {
a = b;
return true;
}
return false;
}
struct Edge {
ll to, cap, rev;
Edge(ll _to, ll _cap, ll _rev) {
to = _to; cap = _cap; rev = _rev;
}
};
using Edges = vector<Edge>;
using Graph = vector<Edges>;
void add_edge(Graph& G, ll from, ll to, ll cap, bool revFlag, ll revCap) {
G[from].push_back(Edge(to, cap, (ll)G[to].size()));
if (revFlag)G[to].push_back(Edge(from, revCap, (ll)G[from].size() - 1));
}
template<class Abel> struct UnionFind {
vector<int> par;
vector<int> rank;
vector<Abel> diff_weight;
UnionFind(int n = 1, Abel SUM_UNITY = 0) {
init(n, SUM_UNITY);
}
void init(int n = 1, Abel SUM_UNITY = 0) {
par.resize(n); rank.resize(n); diff_weight.resize(n);
for (int i = 0; i < n; ++i) par[i] = i, rank[i] = 0, diff_weight[i] = SUM_UNITY;
}
int root(int x) {
if (par[x] == x) {
return x;
}
else {
int r = root(par[x]);
diff_weight[x] += diff_weight[par[x]];
return par[x] = r;
}
}
Abel weight(int x) {
root(x);
return diff_weight[x];
}
bool issame(int x, int y) {
return root(x) == root(y);
}
bool merge(int x, int y, Abel w) {
w += weight(x); w -= weight(y);
x = root(x); y = root(y);
if (x == y) return false;
if (rank[x] < rank[y]) swap(x, y), w = -w;
if (rank[x] == rank[y]) ++rank[x];
par[y] = x;
diff_weight[y] = w;
return true;
}
Abel diff(int x, int y) {
return weight(y) - weight(x);
}
};
void solve(){
ll n,q;
cin>>n>>q;
UnionFind<ll> uni(n);
Array cost(n);
REP(_,q){
ll t,a,b;
cin>>t>>a>>b;
if(t==1){
a--;b--;
a=uni.root(a);
b=uni.root(b);
uni.merge(a,b,cost[b]-cost[a]);
}else if(t==2){
a--;
cost[uni.root(a)]+=b;
}else{
a--;
ll r=uni.root(a);
cout<<cost[r]+uni.diff(r,a)<<en;
}
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
solve();
//ll t;cin>>t;REP(i,t) solve();
return 0;
}
momohara