圆方树RE+MLE求助
查看原帖
圆方树RE+MLE求助
1034667
Elysian_Realme楼主2024/7/5 13:27
// Problem: P4606 [SDOI2018] 战略游戏
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P4606
// Memory Limit: 488 MB
// Time Limit: 10000 ms
// 
// By:lmq
// AC Time:2024-07-04 12:50:06

#include <bits/stdc++.h>
using namespace std;
inline int read(){
	int x=0,f=1;char ch=getchar();
	while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
	while (ch>='0'&&ch<='9'){x=x*10+ch-48;ch=getchar();}
	return x*f;
}
const int N=2e5+5;
int t,n,m,ex,tim;
stack<int> st;
int w[N],d[N],f[N][50],p[N][50];
int dfn[N],low[N],a[N];
vector<int> g[N],e[N];
void solve(int u,int v){
	int k;ex++;
	do{
		k=st.top(),st.pop();
		e[k].push_back(ex);
		e[ex].push_back(k);
	}while(k!=v);
	e[u].push_back(ex);
	e[ex].push_back(u);
}
void tarjan(int u,int fa){
	st.push(u);
	dfn[u]=low[u]=++tim;
	for(int v:g[u]){
		if(!dfn[v]){
			tarjan(v,u);
			low[u]=min(low[u],low[v]);
			if(low[v]>=dfn[u])
				solve(u,v);
		}else if(v!=fa)
			low[u]=min(low[u],dfn[v]);
	}
}
void dfs(int u,int fa){
	d[u]=d[fa]+1;
	w[u]=(u<=n);
	f[u][0]=fa,p[u][0]=w[u];
	for(int i=1;i<=30;i++)
		f[u][i]=f[f[u][i-1]][i-1],p[u][i]=p[u][i-1]+p[f[u][i-1]][i-1];
	for(int v:e[u])
		if(v!=fa)
			dfs(v,u);
}
int lca(int x,int y){
	if(d[x]<d[y])swap(x,y);
	int ret=0;
	while(d[x]>d[y]){
		int k=__lg(d[x]-d[y]);
		ret+=p[x][k];
		x=f[x][k];
	}
	if(x==y)return ret;
	for(int i=30;i>=0;i--)
		if(f[x][i]!=f[y][i]){
			ret+=p[x][i];
			ret+=p[y][i];
			x=f[x][i];
			y=f[y][i];
		}
	return ret;
}
int lcb(int x,int y){
	if(d[x]<d[y])swap(x,y);
	int ret=0;
	while(d[x]>d[y]){
		int k=__lg(d[x]-d[y]);
		ret+=p[x][k];
		x=f[x][k];
	}
	if(x==y)return ret+w[x];
	for(int i=30;i>=0;i--)
		if(f[x][i]!=f[y][i]){
			ret+=p[x][i];
			ret+=p[y][i];
			x=f[x][i];
			y=f[y][i];
		}
	return ret+w[f[x][0]];
}
bool cmp(int a,int b){
	return dfn[a]<dfn[b];
}
signed main(){
	cin>>t;
	while(t--){
		memset(f,0,sizeof(f));
		tim=0;
		n=read(),m=read();ex=n;
		for(int i=1;i<=m;i++){
			int u=read(),v=read();
			g[u].push_back(v);
			g[v].push_back(u);
		}
		tarjan(1,0);
		dfs(1,0);
		int q=read();
		for(int i=1;i<=q;i++){
			int s=read();
			for(int j=1;j<=s;j++)
				a[j]=read();
			sort(a+1,a+1+s,cmp);
			int ans=0;
			for(int j=1;j<s;j++){
				ans+=lca(a[j],a[j+1]);
			}
			ans+=lcb(a[s],a[1]);
			cout<<ans/2-s+1<<endl;
		}
		// cout<<endl;
	}
	return 0;
}
// 某一日,祂从天坠落。人们抬头仰望,于是看见了星空。
// 星月送来神的女儿,她愿成为人的伴侣。
// 长风化作她的轺车,四海落成她的园圃。鸟雀衔来善的种子,百花编织爱的颂歌。
// 她便是这样降生于世,行于大地,与人类一同长大,与世界一起发芽。
// 而今,「终焉」之时将至。
// 而今,「归去」之时已至。
// 就此告别吧,美丽的世界。
// 此后,将有「群星」闪耀,因为我如今来过。
// 此后,将有「百花」绽放,因为我从未离去。
// 请将我的箭、我的花、与我的爱,织成新生的种子,带向那枯萎的大地。
// 然后,便让它开出永恒而无瑕的…「人性之华」吧。
// 「我名为爱莉希雅……」
// 「最初的律者,人之律者。」
2024/7/5 13:27
加载中...