其他分享
首页 > 其他分享> > C20220712T2 牛半仙的妹子图

C20220712T2 牛半仙的妹子图

作者:互联网

给定 \(n\) 个点和 \(m\) 条边,起点 \(s\) ,每个点有颜色。给定多组 \([l,r]\) ,求最大走 \(l...r\) 边权所有可以走到的不同颜色数之和。(同一种颜色在不同区间内算多组)。 \(n,m\leq 5\times 10^5,q\leq 10^5,type\leq 600\) 。


将原图转换成最小生成树是等效的,因为最大值最小的瓶颈边一定在最小生成树上。于是可以从起点进行 \(DFS\) ,求出到每个点的边权最大,然后存到 \(typ\) 数组中表示同一类型的最优点。最后每次查询答案都直接 \(O(600)\) 暴力得出解。

ll ecnt=1,typ[500005];
piii e[500005];
ll ans[1005],anss;
ll maxn[500005],fa[500005];

ll find(ll x){
	return (fa[x]==x)?x:fa[x]=find(fa[x]);
}

struct edge{
	ll to,nxt,w;
}ee[1000005];

ll head[500005];
void adde(ll u,ll v,ll w){
	ee[++ecnt].nxt=head[u];
	ee[ecnt].to=v;
	ee[ecnt].w=w;
	head[u]=ecnt;
}
void dfs(ll x,ll fa){
	for(int i=head[x];i;i=ee[i].nxt){
		int y=ee[i].to;
		if(y==fa)
			continue;
		maxn[y]=std::max(maxn[x],ee[i].w);
		ans[typ[y]]=std::min(maxn[y],ans[typ[y]]);
		dfs(y,x);
	}
}

ll n,m,q,x,op,M,las,same=1;
int main(){
	n=in(),m=in(),q=in(),x=in(),op=in();
	if(op==1)
		M=in();
	FOR(i,1,n){
		typ[i]=in();
		fa[i]=i;
	}
	FOR(i,1,600)
		ans[i]=10000000000;
	FOR(i,1,m){
		ll u=in(),v=in(),w=in();
		e[i]=mp(w,mp(u,v));
	}
	sort(e+1,e+m+1);
	FOR(i,1,m){
		if(find(e[i].sf)!=find(e[i].ss)){
			fa[find(e[i].sf)]=find(e[i].ss);
			adde(e[i].sf,e[i].ss,e[i].first);
			adde(e[i].ss,e[i].sf,e[i].first);
		}
	}
	ans[typ[x]]=0;
	dfs(x,x);
	FOR(i,1,q){
		anss=0;
		ll l=in(),r=in();
		if(op==1){
			l=(l^las)%M+1;
			r=(r^las)%M+1;
		}
		if(l>r)
			std::swap(l,r);
		FOR(j,1,600){
			if(ans[j]<=r){
				anss+=std::min(r-ans[j]+1,r-l+1); 
			}
		}
		las=anss;
		printf("%lld\n",anss);
	}
	return 0;
}

标签:半仙,ee,ll,C20220712T2,fa,ans,妹子,typ,find
来源: https://www.cnblogs.com/zhouzizhe/p/16639827.html