QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#688572#2214. Link Cut DigraphBreakingtdascAC ✓576ms47296kbC++144.0kb2024-10-30 11:06:382024-10-30 11:06:40

Judging History

你现在查看的是最新测评结果

  • [2024-10-30 11:06:40]
  • 评测
  • 测评结果:AC
  • 用时:576ms
  • 内存:47296kb
  • [2024-10-30 11:06:38]
  • 提交

answer

#include <bits/stdc++.h>
#define rep(i,n) for(int i=0,del##i##verme=int(n);i<del##i##verme;++i)
#define rep1(i,n) for(int i=1,parano##i##a=int(n);i<=parano##i##a;++i)
#define per(i,n) for(int i=int(n)-1;i>=0;--i)
#define per1(i,n) for(int i=int(n);i>=1;--i)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define y0 LingLuo
#define y1 VividCycle
typedef long long ll;
typedef unsigned long long ull;
typedef long double ldb;
using namespace std;
const ll mod1=998244353;
const ll mod2=1000000007;
unsigned time_related_rand()
{
	return unsigned(std::chrono::steady_clock::now().time_since_epoch().count());
}
struct dsu{
	ll answer;int cnt;
	int p[100005],siz[100005];
	int l[100005],r[100005];
	void init(int n)
	{
		answer=0;cnt=0;
		rep1(i,n)
		{
			p[i]=i;siz[i]=1;
		}
	}
	int getp(int x)
	{
		return (p[x]==x)?x:(getp(p[x]));
	}
	void merge(int x,int y)
	{
		x=getp(x);y=getp(y);
		if(x==y)
		{
			l[++cnt]=0;r[cnt]=0;return ;
		}
		if(siz[x]>siz[y]) swap(x,y);
		p[x]=y;answer+=siz[x]*1ll*siz[y];siz[y]+=siz[x];
		l[++cnt]=x;r[cnt]=y;
	//	cout<<"after adding "<<answer<<endl;
	}
	void revert()
	{
		if(l[cnt])
		{
			siz[r[cnt]]-=siz[l[cnt]];p[l[cnt]]=l[cnt];answer-=siz[l[cnt]]*1ll*siz[r[cnt]];
		}
		--cnt;
	//	cout<<"after reverting "<<answer<<endl;
	}
};
dsu D;
int n,m,u[250005],v[250005];
vector<int> nodes; 
ll result[250005];
vector<int> to[100005],fr[100005];
bool vis[100005];int scc[100005],val[100005];int ct;
vector<int> dfn;
void dfs_dfn(int x)
{
	vis[x]=true;for(int y:to[x]) if(!vis[y]) dfs_dfn(y);
	dfn.pb(x);
}
void dfs_scc(int x,int y)
{
	scc[x]=y;for(int z:fr[x]) if(!scc[z]) dfs_scc(z,y);
}
void solve(int l,int r,vector<pair<pair<int,int>,int> > &edges)
{
	int m=(l+r)>>1;
//	cout<<l<<" ~ "<<r<<endl;
//	for(auto P:edges) cout<<P.fi.fi<<" - "<<P.fi.se<<"  ("<<P.se<<")"<<endl;
	nodes.clear();
	for(auto P:edges)
	{
		nodes.pb(P.fi.fi);nodes.pb(P.fi.se);
	}
	sort(nodes.begin(),nodes.end());
	nodes.erase(unique(nodes.begin(),nodes.end()),nodes.end());
	ct=0;dfn.clear();
	for(int x:nodes)
	{
		to[x].clear();fr[x].clear();vis[x]=false;scc[x]=0;
	}
	for(auto P:edges)
	{
		if(P.se>m) continue;
		to[P.fi.fi].pb(P.fi.se);fr[P.fi.se].pb(P.fi.fi);
	}
	for(int x:nodes)
	{
		if(!vis[x]) dfs_dfn(x);
	}
	reverse(dfn.begin(),dfn.end());
	for(int x:dfn)
	{
		if(!scc[x])
		{
			dfs_scc(x,++ct);
			val[ct]=x;
		}
	}
//	for(int x:nodes) cout<<x<<" scc "<<scc[x]<<endl;
	if(l==r)
	{
		int curt=0;
		for(int x:nodes) if(val[scc[x]]!=x)
		{
	//		cout<<x<<" addedge "<<val[scc[x]]<<endl;
			++curt;D.merge(x,val[scc[x]]);
		}
		result[l]=D.answer;
		rep(i,curt) D.revert();
	//	cout<<"revert "<<curt<<endl;
	}
	else
	{
		int curt=0;
		for(int x:nodes) if(val[scc[x]]!=x)
		{
	//		cout<<x<<" addedge "<<val[scc[x]]<<endl;
			++curt;D.merge(x,val[scc[x]]);
		}
		vector<pair<pair<int,int>,int> > E1,E2;
		E1.clear();E2.clear();
		for(auto P:edges)
		{
			if(scc[P.fi.fi]==scc[P.fi.se]) E1.pb(P);
			else E2.pb(mp(mp(D.getp(P.fi.fi),D.getp(P.fi.se)),P.se));
		}
		solve(m+1,r,E2);
		rep(i,curt) D.revert();
	//	cout<<"revert"<<" "<<curt<<endl;
		solve(l,m,E1);
	}
}
vector<pair<pair<int,int>,int> > edge;
int main()
{
	ios_base::sync_with_stdio(false);cin.tie(0);
	cin>>n>>m;rep1(i,m)cin>>u[i]>>v[i];
	D.init(n);rep1(i,m)edge.pb(mp(mp(u[i],v[i]),i));
	solve(1,m,edge);
	rep1(i,m) cout<<result[i]<<"\n";
	return 0;
}
/* things to check
1.  int overflow or long long memory need
2.  recursion/array/binary search/dp/loop bounds
3.  precision
4.  special cases(n=1,bounds)
5.  delete debug statements
6.  initialize(especially multi-tests)
7.  = or == , n or m ,++ or -- , i or j , > or >= , < or <=
8.  keep it simple and stupid
9.  do not delete, use // instead
10. operator priority
11. is there anything extra to output?
12. ...
*/

/* something to think about
1. greedy? dp? searching? dp with matrix/ segment tree? binary search?
2. If contains "not", why not ?????? or few affect?
*/

詳細信息

Test #1:

score: 100
Accepted
time: 564ms
memory: 43540kb

Test #2:

score: 0
Accepted
time: 576ms
memory: 43440kb

Test #3:

score: 0
Accepted
time: 566ms
memory: 43848kb

Test #4:

score: 0
Accepted
time: 534ms
memory: 47108kb

Test #5:

score: 0
Accepted
time: 558ms
memory: 43648kb

Test #6:

score: 0
Accepted
time: 560ms
memory: 44012kb

Test #7:

score: 0
Accepted
time: 560ms
memory: 43164kb

Test #8:

score: 0
Accepted
time: 566ms
memory: 43864kb

Test #9:

score: 0
Accepted
time: 535ms
memory: 47296kb

Test #10:

score: 0
Accepted
time: 554ms
memory: 44368kb

Test #11:

score: 0
Accepted
time: 558ms
memory: 43780kb

Test #12:

score: 0
Accepted
time: 562ms
memory: 43772kb

Test #13:

score: 0
Accepted
time: 534ms
memory: 46804kb

Test #14:

score: 0
Accepted
time: 528ms
memory: 46452kb

Test #15:

score: 0
Accepted
time: 378ms
memory: 37996kb

Test #16:

score: 0
Accepted
time: 514ms
memory: 37912kb

Test #17:

score: 0
Accepted
time: 511ms
memory: 37380kb

Test #18:

score: 0
Accepted
time: 512ms
memory: 37440kb

Test #19:

score: 0
Accepted
time: 559ms
memory: 43736kb

Test #20:

score: 0
Accepted
time: 526ms
memory: 45612kb

Test #21:

score: 0
Accepted
time: 531ms
memory: 45220kb

Test #22:

score: 0
Accepted
time: 531ms
memory: 45048kb

Test #23:

score: 0
Accepted
time: 520ms
memory: 45972kb

Test #24:

score: 0
Accepted
time: 526ms
memory: 45400kb

Test #25:

score: 0
Accepted
time: 519ms
memory: 45540kb

Test #26:

score: 0
Accepted
time: 522ms
memory: 43508kb

Test #27:

score: 0
Accepted
time: 519ms
memory: 43216kb