您的位置:首页 > 其它

Codeforces 601D. Acyclic Organic Compounds(四个愿望一次满足)

2017-12-12 13:56 453 查看

  trie合并的裸题...因为最多只有n个点,所以最多合并n次,复杂度$O(N*26)$。

#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<algorithm>
#define ll long long
using namespace std;
const int maxn=500010, inf=1e9;
const ll mod=233333333333333333;
struct poi{int too, pre;}e[maxn<<1];
int n, x, y, N, tot, sum, skip, ANS, ANSNUM;
int c[maxn], last[maxn], son[maxn], size[maxn], cnt[maxn], ans[maxn];
ll b[maxn], hs[maxn];
char s[maxn];
inline void read(int &k)
{
int f=1; k=0; char c=getchar();
while(c<'0' || c>'9') c=='-' && (f=-1), c=getchar();
while(c<='9' && c>='0') k=k*10+c-'0', c=getchar();
k*=f;
}
inline void add(int x, int y){e[++tot]=(poi){y, last[x]}; last[x]=tot;}
void dfs1(int x, int fa)
{
size[x]=1; b[x]=hs[x]=(hs[fa]*27+s[x]-'a'+1)%mod;
for(int i=last[x], too;i;i=e[i].pre)
if((too=e[i].too)!=fa)
{
dfs1(too, x);
size[x]+=size[too];
if(size[too]>size[son[x]]) son[x]=too;
}
}
void update(int x, int fa, int delta)
{
if(delta==1) sum+=(!cnt[hs[x]]);
cnt[hs[x]]+=delta;
for(int i=last[x], too;i;i=e[i].pre)
if((too=e[i].too)!=fa && too!=skip) update(too, x, delta);
}
void dfs2(int x, int fa, bool heavy)
{
for(int i=last[x], too;i;i=e[i].pre)
if((too=e[i].too)!=fa && too!=son[x]) dfs2(too, x, 0);
if(son[x]) dfs2(son[x], x, 1), skip=son[x];
update(x, fa, 1); ans[x]=sum; skip=0;
if(!heavy) update(x, fa, -1), sum=0;
if(ans[x]+c[x]>ANS) ANS=ans[x]+c[x], ANSNUM=1;
else if(ans[x]+c[x]==ANS) ANSNUM++;
}
int main()
{
read(n);
for(int i=1;i<=n;i++) read(c[i]);
scanf("%s", s+1);
for(int i=1;i<n;i++) read(x), read(y), add(x, y), add(y, x);
dfs1(1, 0);
N=n; sort(b+1, b+1+N); N=unique(b+1, b+1+N)-b-1;
for(int i=1;i<=n;i++) hs[i]=lower_bound(b+1, b+1+N, hs[i])-b;
dfs2(1, 0, 1); printf("%d\n%d", ANS, ANSNUM);
}
View Code

  还可以hash之后写线段树合并,复杂度$O(NlogN)$。(真的懒得写了T T

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: