社区讨论

虚树30分WA+AC+TLE,求调

P4103[HEOI2014] 大工程参与者 2已保存回复 2

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
2 条
当前快照
1 份
快照标识符
@mi3yj0ue
此快照首次捕获于
2025/11/18 10:31
4 个月前
此快照最后确认于
2025/11/18 10:31
4 个月前
查看原帖
CPP
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=8000010;
int n,q,k,a[N],uu,vv,hea[N],edge[N],nxt[N],cnt;
int he[N],eg[N],nx[N],cnt1;
int son[N],siz[N],idx,id[N],fa[N],tot[N],dep[N];
void add(int u,int v){edge[++cnt]=v,nxt[cnt]=hea[u],hea[u]=cnt;return ;}
void add1(int u,int v){eg[++cnt1]=v,nx[cnt1]=he[u],he[u]=cnt1;return ;}
void dfs1(int now,int p){
	siz[now]=1,fa[now]=p,dep[now]=dep[p]+1,id[now]=++idx;
	for(int jj=hea[now];jj;jj=nxt[jj]){
		int to=edge[jj];
		if(to==p) continue;
		dfs1(to,now);
		siz[now]+=siz[to];
		if(siz[son[now]]<siz[to]) siz[now]=to;
	}
	return ;
}
void dfs2(int now,int p){
	tot[now]=p;
	if(son[now]) dfs2(son[now],p);
	for(int jj=hea[now];jj;jj=nxt[jj]){
		int to=edge[jj];
		if(to==fa[now]||to==son[now]) continue;
		dfs2(to,to);
	}
	return ;
}
int lca(int x,int y){
	while(tot[x]!=tot[y]){
		if(dep[tot[x]]<dep[tot[y]]) swap(x,y);
		x=fa[tot[x]];
	}
	return dep[x]<dep[y]?x:y;
}
bool cmp(int x,int y){return id[x]<id[y];}
int st[N],to1,si[N];
bool pd[N];
void build(){
	sort(a+1,a+k+1,cmp);
	st[to1=1]=1;
	if(a[1]!=1) st[++to1]=a[1];
	for(int j=2;j<=k;++j){
		int l=lca(st[to1],a[j]);
		while(to1>1&&dep[l]<=dep[st[to1-1]]){
			add1(st[to1-1],st[to1]),--to1;
		}
		if(l!=st[to1]){
			add1(l,st[to1]),st[to1]=l;
		}
		st[++to1]=a[j];
	}
	while(to1){
		add1(st[to1-1],st[to1]),--to1;
	}
	return ;
}
int dpmin[N],dpmax[N],cou[N],dpans[N],ans1,ans2,ans3;
void dfs3(int now){
	if(pd[now]) dpmin[now]=0,dpmax[now]=0;
	for(int jj=he[now];jj;jj=nx[jj]){
		int to=eg[jj];
		dfs3(to);
		ans2=max(dpmax[to]+dep[to]-dep[now]+dpmax[now],ans2);
		dpmax[now]=max(dpmax[now],dpmax[to]+dep[to]-dep[now]);
		ans1=min(dpmin[to]+dep[to]-dep[now]+dpmin[now],ans1);
		dpmin[now]=min(dpmin[now],dpmin[to]+dep[to]-dep[now]);
	}
	return ;
}
void dfs5(int now){
	if(pd[now]||now==1) si[now]=1;
	dpans[now]=0;
	for(int jj=he[now];jj;jj=nx[jj]){
		int to=eg[jj];
		dfs5(to);
		dpans[to]+=si[to]*(dep[to]-dep[now]);
		ans3+=dpans[to]*si[now]+dpans[now]*si[to];
		dpans[now]+=dpans[to];
		si[now]+=si[to];
	}
	dpmin[now]=2e17,dpmax[now]=-2e17,he[now]=0;
	return ;
}
signed main(){
	ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
	cin>>n;
	for(int i=1;i<=n;++i) dpmax[i]=-2e17,dpmin[i]=2e17;
	for(int i=1;i<n;++i){
		cin>>uu>>vv;
		add(uu,vv),add(vv,uu);
	}
	dfs1(1,0),dfs2(1,1);
	cin>>q;
	for(int i=1;i<=q;++i){
		ans1=2e17,ans2=-2e17,ans3=0;
		cin>>k;
		for(int j=1;j<=k;++j){
			cin>>a[j];
			pd[a[j]]=1;
		}
		build();
		dfs3(1);
		dfs5(1);
		if(!pd[1]) ans3-=dpans[1];
		cout<<ans3<<' '<<ans1<<' '<<ans2<<'\n';
		for(int j=1;j<=k;++j) pd[a[j]]=0;
	}
	return 0;
}

回复

2 条回复,欢迎继续交流。

正在加载回复...