ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

YbtOJ-毒瘤染色【LCT】

2022-02-07 21:34:43  阅读:178  来源: 互联网

标签:LCT return leq YbtOJ ll 毒瘤 fa ans void


正题


题目大意

开始时有一张\(n\)个点没有边的图,\(q\)次操作加入一条边,如果加入后图是一个沙漠(只有边仙人掌的图)时才能够加入。

每次加入后询问:开始所有点都是白色,\(k\)次随机挑一个点染黑,求最后白色点的连通块数和黑色点的连通块数的和。

强制在线

\(1\leq n\leq 10^5,1\leq q\leq 3\times 10^5,1\leq k\leq 10^9\)


解题思路

因为强制在线肯定需要用\(LCT\)维护,至于仙人掌我们维护在环上的边就好了。

然后考虑怎么求答案。

仙人掌的连通块数=点数-边数+环数。

至于本题我们可以考虑这些东西存在的期望数量。

设\(w_i\)表示指定\(i\)个点是白点的概率,那么显然就是\((\frac{n-i}{n})^k\)。

然后设\(b_i\)表示指定\(i\)个点是黑点的概率,我们考虑容斥指定一些点是白点就是

\[b_i=\sum_{j=0}^i\binom{i}{j}(-1)^j\left(\frac{n-j}{n}\right)^k \]

这样是\(O(i)\)的,但是其实我们只有求环的出现概率时这个值会很大,但是环的大小和不超过\(n\),所以可以在需要的时候暴力求。

时间复杂度:\(O(q\log n)\)


code

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<stack>
#define ll long long
using namespace std;
const ll N=2e5+10,P=998244353;
struct LCT{
	ll fa[N],t[N][2],siz[N];
	bool w[N],v[N],lazy[N],r[N],p[N],hp[N];
	stack<ll> s;
	bool Nroot(ll x)
	{return fa[x]&&(t[fa[x]][0]==x||t[fa[x]][1]==x);}
	bool Direct(ll x)
	{return t[fa[x]][1]==x;}
	void PushUp(ll x){
		siz[x]=siz[t[x][0]]+siz[t[x][1]]+(!p[x]);
		w[x]=(p[x]&v[x])|w[t[x][0]]|w[t[x][1]];
		hp[x]=p[x]|hp[t[x][0]]|hp[t[x][1]]; 
		return;
	}
	void Rev(ll x)
	{r[x]^=1;swap(t[x][0],t[x][1]);return;}
	void Rvy(ll x){w[x]=hp[x];lazy[x]=v[x]=1;return;}
	void PushDown(ll x){
		if(r[x])Rev(t[x][0]),Rev(t[x][1]),r[x]=0;
		if(lazy[x]){
			if(t[x][0])Rvy(t[x][0]);
			if(t[x][1])Rvy(t[x][1]);
			lazy[x]=0;
		}
		PushUp(x);return;
	}
	void Rotate(ll x){
		ll y=fa[x],z=fa[y];
		ll xs=Direct(x),ys=Direct(y);
		ll w=t[x][xs^1];
		if(Nroot(y))t[z][ys]=x;
		t[y][xs]=w;t[x][xs^1]=y;
		if(w)fa[w]=y;fa[x]=z;fa[y]=x;
		PushUp(y);PushUp(x);return; 
	}
	void Splay(ll x){
		ll y=x;s.push(x);
		while(Nroot(y))y=fa[y],s.push(y);
		while(!s.empty())PushDown(s.top()),s.pop();
		while(Nroot(x)){
			y=fa[x];
			if(!Nroot(y))Rotate(x);
			else if(Direct(x)==Direct(y))
				Rotate(y),Rotate(x);
			else Rotate(x),Rotate(x);
		}
		return;
	}
	void Access(ll x){
		for(ll y=0;x;y=x,x=fa[x])
			Splay(x),t[x][1]=y,PushUp(x);
		return;
	}
	void MakeRoot(ll x)
	{Access(x);Splay(x);Rev(x);return;}
	void Link(ll x,ll y)
	{MakeRoot(x);fa[x]=y;Access(x);return;}
	void Split(ll x,ll y)
	{MakeRoot(x);Access(y);Splay(y);return;}
}T;
ll n,q,k,op,ans,fa[N],inv[N],fac[N],fnv[N];
ll find(ll x)
{return (fa[x]==x)?x:(fa[x]=find(fa[x]));}
ll power(ll x,ll b){
	ll ans=1;
	while(b){
		if(b&1)ans=ans*x%P;
		x=x*x%P;b>>=1;
	}
	return ans;
}
ll C(ll n,ll m)
{return fac[n]*fnv[m]%P*fnv[n-m]%P;}
ll W(ll x)
{return power((n-x)*inv[n]%P,k);}
ll B(ll x){
	ll ans=0;
	for(ll i=0;i<=x;i++){
		ll w=power((n-i)*inv[n]%P,k);
		w=w*C(x,i)%P;(ans+=w*((i&1)?-1:1))%=P;
	}
	return (ans+P)%P;
}
signed main()
{
	freopen("graph.in","r",stdin);
	freopen("graph.out","w",stdout);
	inv[1]=fnv[0]=fac[0]=1;
	for(ll i=2;i<N;i++)inv[i]=P-inv[P%i]*(P/i)%P;
	for(ll i=1;i<N;i++)fnv[i]=fnv[i-1]*inv[i]%P,fac[i]=fac[i-1]*i%P;
	scanf("%lld%lld%lld%lld",&n,&q,&k,&op);
	for(ll i=1;i<=n;i++)fa[i]=i,T.siz[i]=1;
	ll w2=W(2),b2=B(2),las=0;
	ans=(W(1)*n+op*B(1)*n)%P;
	int cnt=n;
	while(q--){
		ll x,y;
		scanf("%lld%lld",&x,&y);
		x^=las;y^=las;
		if(find(x)!=find(y)){
			fa[find(x)]=find(y);
			++cnt;T.p[cnt]=T.hp[cnt]=1;
			T.Link(x,cnt);
			T.Link(y,cnt);
			(ans-=w2+op*b2)%=P;
		}
		else if(x!=y){
			T.Split(x,y);
			if(!T.w[y]){
				T.w[y]=T.v[y]=T.lazy[y]=1;
				ll S=T.siz[y];
				(ans+=W(S)-w2)%=P;
				if(op)(ans+=B(S)-b2)%=P;
			}
		}
		ans=(ans+P)%P;
		printf("%lld\n",las=ans);
	}
	return 0;
}

标签:LCT,return,leq,YbtOJ,ll,毒瘤,fa,ans,void
来源: https://www.cnblogs.com/QuantAsk/p/15869452.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有