結果
| 問題 |
No.1054 Union add query
|
| コンテスト | |
| ユーザー |
Shibuyap
|
| 提出日時 | 2020-05-15 22:54:22 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
WA
|
| 実行時間 | - |
| コード長 | 1,745 bytes |
| コンパイル時間 | 2,555 ms |
| コンパイル使用メモリ | 197,180 KB |
| 最終ジャッジ日時 | 2025-01-10 12:02:50 |
|
ジャッジサーバーID (参考情報) |
judge5 / judge3 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 5 WA * 3 |
ソースコード
#include <bits/stdc++.h>
#define rep(i,n) for(int i = 0; i < (n); ++i)
#define drep(i,n) for(int i = (n)-1; i >= 0; --i)
#define srep(i,s,t) for (int i = s; i < t; ++i)
using namespace std;
typedef long long int ll;
typedef pair<int,int> P;
#define yn {puts("Yes");}else{puts("No");}
const int MAX_N = 1000100;
int par_[MAX_N]; // 親
int rank_[MAX_N]; // 木の深さ
ll val[MAX_N];
// n要素で初期化
void UFinit(){
for(int i=0;i<MAX_N;i++){
par_[i] = i;
rank_[i] = 0;
}
}
// 木の根を求める
int find_(int x){
if(par_[x] == x){
return x;
}else{
return par_[x] = find_(par_[x]);
}
}
// xとyの属する集合を併合
void unite(int x, int y){
x = find_(x);
y = find_(y);
if(x == y) return;
if(rank_[x] < rank_[y]){
val[x] -= val[y];
par_[x] = y;
}else{
val[y] -= val[x];
par_[y] = x;
if(rank_[x] == rank_[y]) rank_[x]++;
}
}
// xとyが同じ集合に属するか否か
bool same(int x, int y){
return find_(x) == find_(y);
}
ll calc(int x){
ll res = val[x];
if(par_[x] == x){
return res;
}
res += calc(par_[x]);
return res;
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(0);
UFinit();
int n, q;
cin >> n >> q;
vector<int> ans;
rep(i,q){
int t, a, b;
cin >> t >> a >> b;
if(t == 1){
if(same(a,b))continue;
unite(a,b);
}else if(t == 2){
int x = find_(a);
val[x] += b;
}else if(t == 3){
ans.push_back(calc(a));
}
}
rep(i,ans.size()) cout << ans[i] << endl;
if(ans.size() == 0) cout << endl;
return 0;
}
Shibuyap