이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include <bits/stdc++.h>
using namespace std;
struct edge{
int group, nod, cnt;
bool operator < (const edge &aux)const{
if(group != aux.group) return group < aux.group;
if(nod != aux.nod) return nod < aux.nod;
return cnt < aux.cnt;
}
};
int n, m;
int TT[100001], SZ[100001];
long long Sol = 0;
set <edge> in[100001];
set <edge> out[100001];
inline int find(int x){
if(x != TT[x]) return (TT[x] = find(TT[x]));
return x;
}
inline void unite(int x, int y){
if(find(x) == find(y)) return ;
if(out[x].size() + in[x].size() < out[y].size() + in[y].size()) swap(x, y);
Sol = Sol + 2LL * SZ[x] * SZ[y];
// set <edge> :: iterator it = out[x].lower_bound({y, 0, 0});
// set <edge> :: iterator aux;
// while(it != out[x].end() && it->group == y){
// Sol = Sol - 1LL * SZ[y] * ;
// out[x].erase
// }
for(auto it : out[x]){
int z = find(it.group);
if(z == y || z == x) continue ;
Sol = Sol + 1LL * SZ[y] * it.cnt * SZ[z];
}
int sz = in[x].size();
for(auto it : out[y]){
int z = find(it.group);
if(z == y) continue ;
if(z == x){
set <edge> :: iterator it2 = in[x].lower_bound({y, 0, 0});
in[x].erase(it2);
--sz;
Sol = Sol - 1LL * SZ[x] * it.cnt;
continue ;
}
Sol = Sol + 1LL * SZ[x] * SZ[z] * it.cnt;
set <edge> :: iterator it2 = out[x].lower_bound({z, 0, 0});
if(it2 == out[x].end() || it2->group != z) out[x].insert({z, 0, it.cnt});
else{
int cnt = it2->cnt + it.cnt;
out[x].erase(it2);
out[x].insert({z, 0, cnt});
}
it2 = in[z].lower_bound({y, 0, 0});
int nod = it2->nod, cnt = it2->cnt;
in[z].erase(it2);
in[z].insert({x, nod, cnt});
}
Sol = Sol + 1LL * SZ[y] * sz;
for(auto it : in[y]){
int z = find(it.group);
if(z == y) continue ;
if(z == x){
set <edge> :: iterator it2 = out[x].lower_bound({y, 0, 0});
out[x].erase(it2);
Sol = Sol - 1LL * SZ[y] * it.cnt;
continue ;
}
set <edge> :: iterator it2 = in[x].lower_bound({z, it.nod, 0});
if(it2 == in[x].end() || it2->group != z || it2->nod != it.nod){
in[x].insert({z, it.nod, it.cnt});
Sol = Sol + SZ[x];
}
it2 = out[z].lower_bound({y, 0, 0});
int cnt = it2->cnt;
out[z].erase(it2);
it2 = out[z].lower_bound({x, 0, 0});
if(it2 != out[z].end()){
cnt += it2->cnt;
out[z].erase(it2);
}
out[z].insert({x, 0, cnt});
}
TT[y] = x;
SZ[x] += SZ[y];
for(auto it : out[y]){
int z = find(it.group);
if(z == x) continue ;
set <edge> :: iterator it2 = in[x].lower_bound({z, 0, 0});
if(it2 != in[x].end() && it2->group == z){
unite(x, z);
x = find(x);
}
}
for(auto it : in[y]){
int z = find(it.group);
if(z == x) continue ;
set <edge> :: iterator it2 = out[x].lower_bound({z, 0, 0});
if(it2 != out[x].end() && it2->group == z){
unite(x, z);
x = find(x);
}
}
}
int main()
{
// freopen("1.in", "r", stdin);
// freopen("1.out", "w", stdout);
scanf("%d%d", &n, &m);
for(int i = 1; i <= n ; ++i) TT[i] = i, SZ[i] = 1;
int x, y, fx, fy;
set <edge> :: iterator it;
for(int i = 1; i <= m ; ++i){
scanf("%d%d", &x, &y);
fx = x; fy = y;
if(find(x) == find(y)){
printf("%lld\n", Sol);
continue ;
}
x = find(x); y = find(y);
it = out[y].lower_bound({x, 0, 0});
if(it != out[y].end() && it->group == x){
unite(x, y);
}
else{
it = in[y].lower_bound({x, fx, 0});
if(it != in[y].end() && it->group == x && it->nod == fx){
printf("%lld\n", Sol);
continue ;
}
Sol += SZ[y];
it = out[x].lower_bound({y, 0, 0});
if(it != out[x].end() && it->group == y){
int cnt = it->cnt + 1;
out[x].erase(it);
out[x].insert({y, 0, cnt});
}
else out[x].insert({y, 0, 1});
in[y].insert({x, fx, 1});
}
printf("%lld\n", Sol);
}
return 0;
}
컴파일 시 표준 에러 (stderr) 메시지
joitter2.cpp: In function 'int main()':
joitter2.cpp:137:19: warning: variable 'fy' set but not used [-Wunused-but-set-variable]
int x, y, fx, fy;
^~
joitter2.cpp:134:10: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
scanf("%d%d", &n, &m);
~~~~~^~~~~~~~~~~~~~~~
joitter2.cpp:140:14: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
scanf("%d%d", &x, &y);
~~~~~^~~~~~~~~~~~~~~~
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |