很自信的打了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;
}
为什么啊啊啊啊啊啊啊啊啊啊,我觉得效果都一样啊