不理解为什么能这样改
查看原帖
不理解为什么能这样改
380337
Dea_He楼主2024/3/9 21:56

很自信的打了Trie合并,中心思想是如果当前结点还没有x这个方案的话,就可以把x插到y上,x.siz加到当前节点的siz中

#include<bits/stdc++.h>
using namespace std;
namespace hw{
	const int MAXN=3e5+5;
	
	int n,w[MAXN],c[MAXN],Mx,Mx_num; 
	
	vector<int>ed[MAXN];
	
	struct node {
		int v[27],siz;
	}seg[MAXN];
	
	void merge(int &x,int &y,int &siz) {
		if (!x) return ;
		if (!y) {
			siz+=seg[x].siz;
			y=x,x=0;
			return ;
		} 
//		siz--;
		for (int i=1;i<=26;i++) merge(seg[x].v[i],seg[y].v[i],siz);
	}
	void dfs(int u,int fa) {
		seg[u].siz=1;
//		printf("%d %c : ",u,c[u]-1+'a');
//		for (int i=0;i<ed[u].size();i++) if (ed[u][i]!=fa) printf("%d ",ed[u][i]);
//		printf("\n");
		for (int i=0;i<ed[u].size();i++) {
			int v=ed[u][i];
			if (v==fa) continue;
			dfs(v,u);
//			seg[u].siz+=seg[v].siz;
			merge(v,seg[u].v[c[v]],seg[u].siz);
		}
		if (seg[u].siz+w[u]==Mx) Mx_num++;
		if (seg[u].siz+w[u]>Mx) Mx=seg[u].siz+w[u],Mx_num=1;
//		printf("%d %d %d\n",u,seg[u].siz,w[u]);
	}
	
	int main() {
		scanf("%d",&n);
		for (int i=1;i<=n;i++) scanf("%d",&w[i]);
		for (int i=1;i<=n;i++) {
			char ch;
			scanf(" %c",&ch);
			c[i]=ch-'a'+1;
		}
		for (int i=1;i<n;i++) {
			int x,y;
			scanf("%d%d",&x,&y);
			ed[x].push_back(y);
			ed[y].push_back(x);
		}
		dfs(1,1);
//		for (int i=1;i<=n;i++) printf("%d ",seg[i].siz);
		printf("%d\n%d",Mx,Mx_num);
		return 0;
	}
}
int main() {
	hw::main();
	return 0;
}

WA on 7,看题解有篇类似的,但是把所有子树的siz加在一起再去求合并后减少的,于是把17行改成21和33行就能过

#include<bits/stdc++.h>
using namespace std;
namespace hw{
	const int MAXN=3e5+5;
	
	int n,w[MAXN],c[MAXN],Mx,Mx_num; 
	
	vector<int>ed[MAXN];
	
	struct node {
		int v[27],siz;
	}seg[MAXN];
	
	void merge(int &x,int &y,int &siz) {
		if (!x) return ;
		if (!y) {
//			siz+=seg[x].siz;
			y=x,x=0;
			return ;
		} 
		siz--;
		for (int i=1;i<=26;i++) merge(seg[x].v[i],seg[y].v[i],siz);
	}
	void dfs(int u,int fa) {
		seg[u].siz=1;
//		printf("%d %c : ",u,c[u]-1+'a');
//		for (int i=0;i<ed[u].size();i++) if (ed[u][i]!=fa) printf("%d ",ed[u][i]);
//		printf("\n");
		for (int i=0;i<ed[u].size();i++) {
			int v=ed[u][i];
			if (v==fa) continue;
			dfs(v,u);
			seg[u].siz+=seg[v].siz;
			merge(v,seg[u].v[c[v]],seg[u].siz);
		}
		if (seg[u].siz+w[u]==Mx) Mx_num++;
		if (seg[u].siz+w[u]>Mx) Mx=seg[u].siz+w[u],Mx_num=1;
//		printf("%d %d %d\n",u,seg[u].siz,w[u]);
	}
	
	int main() {
		scanf("%d",&n);
		for (int i=1;i<=n;i++) scanf("%d",&w[i]);
		for (int i=1;i<=n;i++) {
			char ch;
			scanf(" %c",&ch);
			c[i]=ch-'a'+1;
		}
		for (int i=1;i<n;i++) {
			int x,y;
			scanf("%d%d",&x,&y);
			ed[x].push_back(y);
			ed[y].push_back(x);
		}
		dfs(1,1);
//		for (int i=1;i<=n;i++) printf("%d ",seg[i].siz);
		printf("%d\n%d",Mx,Mx_num);
		return 0;
	}
}
int main() {
	hw::main();
	return 0;
}

为什么啊啊啊啊啊啊啊啊啊啊,我觉得效果都一样啊

2024/3/9 21:56
加载中...