Russian Dolls on the Christmas Tree

題目鏈接:Russian Dolls on the Christmas Tree


顯然可以dfs序轉區間之後上莫隊,不過感覺會被卡。

其實也可以dfs序之後,對詢問區間排序,然後線段樹。

我懶得dfs序,直接樹上啓發式合併做了。

顯然節點兒子信息是可以繼承的,所以繼承重兒子,暴力輕兒子即可。


AC代碼:

#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include<bits/stdc++.h>
//#define int long long
using namespace std;
const int N=2e5+10;
int n,vis[N],res,ans[N],sz[N],son[N],ts;
vector<int> g[N];
inline void add(int a,int b){g[a].push_back(b),g[b].push_back(a);}
void dfs1(int x,int fa){
	sz[x]=1;
	for(auto to:g[x])	if(to!=fa){
		dfs1(to,x);	sz[x]+=sz[to];
		if(sz[to]>sz[son[x]])	son[x]=to;
	}
}
void del(int x,int fa){
	vis[x]=0;
	if(vis[x-1]&&vis[x+1])	res++;
	else if(!vis[x-1]&&!vis[x+1])	res--;
	for(auto to:g[x])	if(to!=fa)	del(to,x);
}
void insert(int x,int fa){
	vis[x]=1;
	if(vis[x-1]&&vis[x+1])	res--;
	else if(!vis[x-1]&&!vis[x+1])	res++;
	for(auto to:g[x])	if(to!=fa)	insert(to,x);
}
void dfs2(int x,int fa){
	for(auto to:g[x])	if(to!=fa&&to!=son[x])	dfs2(to,x),del(to,x);
	if(son[x])	dfs2(son[x],x);
	for(auto to:g[x])	if(to!=son[x]&&to!=fa)	insert(to,x);
	vis[x]=1;
	if(vis[x-1]&&vis[x+1])	res--;
	else if(!vis[x-1]&&!vis[x+1])	res++;
	ans[x]=res;
}
inline void solve(){
	cin>>n;	res=0;
	for(int i=1;i<=n;i++)	vis[i]=son[i]=0,g[i].clear();
	for(int i=1,a,b;i<n;i++)	scanf("%d %d",&a,&b),add(a,b);
	dfs1(1,1);	dfs2(1,1);
	printf("Case #%d: ",++ts);
	for(int i=1;i<=n;i++)	printf("%d%c",ans[i],i==n?'\n':' ');
}
signed main(){
	int T;	cin>>T;	while(T--)	solve();
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章