이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include<bits/stdc++.h>
using namespace std;
#define int long long
set<pair<int,int> > A[200000];
set<int> B[200000];
int ojc[200000],wiel[200000];
int wynik=0;
void rozpatrz(int x,int y);
int find_u(int x)
{
if(ojc[x]==x)
return x;
else return ojc[x]=find_u(ojc[x]);
}
void union_f(int x,int y)
{
x=find_u(x);
y=find_u(y);
if(wiel[x]>wiel[y])
swap(x,y);
for(int i=0;i<2;i++)
{
while(true)
{
auto it=A[x].lower_bound({y,-1});
if(it==A[x].end())
break;
pair<int,int> para=*it;
if(para.first>y)
break;
A[x].erase(para);
B[para.first].erase(para.second);
wynik-=wiel[y];
}
swap(x,y);
}
wynik+=wiel[x]*wiel[y]*2;
vector<pair<int,int> > pomoc;
for(auto i:A[x])
pomoc.push_back({i.second,i.first});
for(auto i : A[x])
{
B[i.first].erase(i.second);
wynik-=wiel[i.first];
}
wynik-=wiel[x]*B[x].size();
wynik+=wiel[x]*B[y].size();
for(auto i:B[x])
A[find_u(i)].erase({x,i});
for(auto i:B[x])
pomoc.push_back({i,x});
wiel[y]+=wiel[x];
ojc[x]=y;
A[x].clear();
B[x].clear();
for(auto i:pomoc)
rozpatrz(i.first,i.second);
}
void rozpatrz(int x,int y)
{
if(find_u(x)==find_u(y))
return;
y=find_u(y);
auto it=A[y].lower_bound({find_u(x),-1});
if(it!=A[y].end())
{
pair<int,int> para=*it;
if(para.first==find_u(x))
{
union_f(x,y);
return;
}
}
if(B[y].find(x)!=B[y].end())
return;
B[y].insert(x);
A[find_u(x)].insert({y,x});
wynik+=wiel[y];
}
int32_t main()
{
cin.tie(0);
cout.tie(0);
ios_base::sync_with_stdio(0);
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++)
ojc[i]=i,wiel[i]=1;
while(m--)
{
int x,y;
cin>>x>>y;
rozpatrz(x,y);
cout<<wynik<<"\n";
}
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |