QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#151611 | #3556. Making Friends on Joitter is Fun | OvO_Zuo | 0 | 4ms | 25032kb | C++14 | 2.9kb | 2023-08-27 10:05:19 | 2023-08-27 10:05:20 |
Judging History
answer
#include <bits/stdc++.h>
using namespace std;
#define fi first
#define se second
typedef long long ll;
const int N=1e5+5;
int n,m;
set<int> edg[N],edg_in[N];
map<int,int> deg[N],deg_in[N];
vector<int> pos[N],tpos;
ll siz[N],fa[N];
ll ans=0;
int get_fa(int x){ return x==fa[x]?x:fa[x]=get_fa(fa[x]);}
void merge(int xx,int yy)
{
int x=get_fa(xx),y=get_fa(yy);
if(x==y) return;
if(siz[x]<siz[y]) swap(x,y);
//cout<<x<<" "<<y<<endl;
int dx=deg[x][y],dy=deg[y][x];
if(dx) deg[x].erase(y),deg_in[y].erase(x),ans-=dx*siz[y];
if(dy) deg[y].erase(x),deg_in[x].erase(y),ans-=dy*siz[x];
ans+=2*siz[x]*siz[y];
//cout<<ans<<endl;
/*
for(auto it=edg_in[x].begin();it!=edg_in[x].end();it++)
if(edg_in[y].find((*it))==edg_in[y].end()) ans+=siz[y];
for(auto it=edg_in[y].begin();it!=edg_in[y].end();it++)
if(edg_in[x].find((*it))==edg_in[x].end()) ans+=siz[x];
*/
int cnta=0,cntb=0;
for(auto it=edg_in[y].begin();it!=edg_in[y].end();it++)
if(edg_in[x].find((*it))==edg_in[x].end()) ++cnta;
else ++cntb;
ans+=(cnta-dx)*siz[x]+siz[y]*(edg_in[x].size()-cntb-dy);
//cout<<ans<<" "<<siz[x]<<" "<<siz[y]<<" "<<cnta<<" "<<cntb<<" "<<dx<<" "<<dy<<" "<<edg_in[x].size()<<endl;
for(auto it=edg_in[y].begin();it!=edg_in[y].end();it++)
{
edg[(*it)].erase(y);
if(edg_in[x].find((*it))==edg_in[x].end()){
if(get_fa((*it))!=x) edg[(*it)].insert(x),edg_in[x].insert((*it));
}
else deg[get_fa((*it))][y]--,deg_in[y][get_fa((*it))]--;
}
for(int t:pos[y])
{
if(edg[t].count(x)) edg[t].erase(x),edg_in[x].erase(t);
pos[x].push_back(t);
}
tpos.clear();
for(auto it:deg[y])
{
deg[x][it.fi]+=it.se,deg_in[it.fi][x]+=it.se;
deg_in[it.fi].erase(y);
if(deg[it.fi].count(x)) tpos.push_back(it.fi);
}
for(auto it:deg_in[y])
{
deg_in[x][it.fi]+=it.se,deg[it.fi][x]+=it.se;
deg[it.fi].erase(y);
if(deg_in[it.fi].count(x)) tpos.push_back(it.fi);
}
edg_in[y].clear();
pos[y].clear();
edg[y].clear();
deg[y].clear();
deg_in[y].clear();
fa[y]=x;
siz[x]+=siz[y];
for(int t:tpos) merge(x,t);
}
void Merge(int xx,int yy)
{
int x=get_fa(xx),y=get_fa(yy);
if(edg[y].find(x)==edg[y].end())
{
if(edg[xx].find(y)!=edg[xx].end()) return;
edg_in[y].insert(xx);
//cout<<y<<" "<<edg_in[y].size()<<endl;
edg[xx].insert(y);
deg_in[y][x]++;
deg[x][y]++;
ans+=siz[y];
return;
}
merge(xx,yy);
}
int main()
{
scanf("%d%d",&n,&m);
int i,x,y;
for(i=1;i<=n;i++) siz[i]=1,fa[i]=i,pos[i].push_back(i);
for(i=1;i<=m;i++)
{
scanf("%d%d",&x,&y);
if(get_fa(x)!=get_fa(y)) Merge(x,y);
printf("%lld\n",ans);
}
return 0;
}
/*
将一个极大团视作一个整体
当加入一条边时,有影响的只有两端所处的团
因为操作次数只有 3e5 次,所以团之间连边的数量也是这个量级
使用set维护该团的出边,加入边 a->b 后发现存在 b团->a团 的边
则将两团合并
*/
詳細信息
Subtask #1:
score: 0
Wrong Answer
Test #1:
score: 0
Wrong Answer
time: 4ms
memory: 25032kb
input:
5 20 4 2 1 5 2 3 2 5 3 2 3 1 4 5 1 2 5 2 1 4 4 1 3 4 5 1 2 4 2 1 4 3 1 3 5 4 3 5 5 3
output:
1 2 3 4 6 7 8 12 15 20 20 20 20 20 20 20 20 20 20 20
result:
wrong answer 9th lines differ - expected: '16', found: '15'
Subtask #2:
score: 0
Skipped
Dependency #1:
0%
Subtask #3:
score: 0
Skipped
Dependency #1:
0%